Object array implemenation in MATLAB OOP - matlab

Suppose that we have this class in MATLAB R2014b :
classdef Pre
properties
Value
end
methods
function obj = Pre(F)
if nargin ~= 0
m = size(F,1);
n = size(F,2);
obj(m,n) = Pre;
for i = 1:m
for j = 1:n
obj(i,j).Value = F(i,j);
end
end
end
end
end
end
1) If we erase if nargin~=0 from this code we have this error :
Error using Pre (line 13)
Not enough input arguments.
Error in Pre (line 15)
obj(m,n) = Pre;
Why? I think this is only checking for number of input arguments !
2) what is obj(m,n) = Pre;? what this line is doing in this code? This is for pre-allocating but how this line can do that?
I checked this class with this syntax: az = Pre([2 3 5;5 3 0])

1) In the line obj(m,n) = Pre; you call Pre without any input argument, so the variable F doesn't exist in that function call. It would therefore fail to do size(F,1) etc. MATLAB prevents this by throwing the error not enough input arguments. As long as you want the possibility to call Pre with or without input arguments, you need to check if an argument exists or not.
2) This does a pre-allocation. By creating an empty Pre at the location (m,n) of obj, MATLAB will initialize obj as matrix of type Pre and size mxn. (You can verify this for normal variables by typing a(2,2) = 0 in the MATLAB console - it will return a 2-by-2 matrix of zeros).

Related

Return property directly when class is called (Matlab)

I have a class called foo with only property M,
classdef foo
properties
M
end
methods
function obj = foo(arg1)
M=arg1;
end
end
end
and I create the object:
F=foo(1)
In C++ it is possible, that when I call F, that I directly get the value of one chosen variable. In my case I would like to get F.M when I just write F. For example this would allow to write
size(F)
instead of writing
size(F.M)
or defining a method size for my class. Is there a way in MATLAB to achieve this?
Edit: In other words, whenever I write F, I want that MATLAB reads it as F.M.
Edit: I will clarify what I want to acchieve.
My class represents a matrix whose values are multivariate infinite sequences with compact support. Thus I have to do a lot of bookkeeping not to mix up all the indices. Things I want to do with my matrix:
Matrix multiplication.
Convolution.
Upsampling, downsampling.
Everything else which is possible in a vector/matrix space.
I thought this is easier to acchieve when I encapsulate all the meta-data (this are the indices of the 0^th entries of the sequence) together with the data.
Because my class is actually a matrix, most operations work on that class in the same way as on ordinary matrices. Therefore I do not want to code it all over again (Because of code-maintenance, less bugs, code-readability).
In C++ I could do it that way. It seems, my approach to that problem is the wrong one in MATLAB.
You have to overload the function size as I mentioned in my comment.
classdef foo
properties
M
end
methods
function obj = foo(arg)
obj.M = arg;
end
function varargout = size(obj, varargin)
if nargin == 1
varargout = size(obj.M);
elseif nargin == 2 && nargout == 1
varargout = size(obj.M, varargin{1})
else
error('Wrong number of input or output arguments.')
end
end
function ret = mtimes(varargin)
try
ret = varargin{1}.M * varargin{2};
catch
ret = varargin{1} * varargin{2}.M;
end
end
end
end
Console Output:
>> F=foo(0:3);
>> size(F)
ans =
1 4
>> size(F, 2)
ans =
4
>> F*(4:7).'
ans =
38
>> (4:7).'*F
ans =
0 4 8 12
0 5 10 15
0 6 12 18
0 7 14 21
I could continue but preparing the console output for StackOverflow is horrible...

How can I declare 2-dimentional array as parameter in function In MATLAB?

I have a function that gets a matrix and do some operations on it.
but I do not know how to declare function's parameter .
this is my function Code:
function D=Shirinkage(a)
D(1,:)=a(1,:);%this is X1
for i=2:4
D(i,4)=0;
for j=1:3
D(i,j)=1/2*(a(1,j)+a(i,j));
D(i,4)=D(i,j)^2 + D(i,4); %object function
end
end
end
I tried a(4,4) instead of a (parameter of the function),but the error does not appear.
Error:
??? Input argument "a" is undefined.
Error in ==> Shirinkage at 3
D(1,:)=a(1,:);%this is X1
also I want to declare D correctly.
appreciating any help.
Edited:
i call my function from a script file , in this way:
I have a 2-dimention array(matrix) its size is : 4*4 and its name is A.
i want my function gets this matrix and do the operation on it and the result can be saved again in it.
A=Shirinkage(A)
e.x. A has this values:
A=[1,2,3,4;2,3,4,5;5,6,7,8;1,2,3,4]
The function you created is working fine. The only recommendation I have to pre-allocate the size of D as it varies in each iteration in your current code.
function D = Shirinkage(a)
D = zeros(size(a));
D(1,:) = a(1,:); %this is X1
for i = 2:4
D(i,4) = 0;
for j = 1:3
D(i,j) = 0.5*(a(1,j) + a(i,j));
D(i,4) = D(i,4) + D(i,j)^2; %object function
end
end
end
The function was called from command window by using the same matrix you have used and it gave the following output.
The error you have posted says that the function hasn't received the argument a. If your script and the function are in the same MATLAB path, this should work perfectly.

First input must be function handle error using arrayfun()

I'm trying to use arrayfun() to map a function over a cell array. The following is happening:
>> arrayfun(solveFunc, equArray)
Error using arrayfun
First input must be a function handle.
Error in solve>genGuess (line 33)
funcVals = abs(arrayfun(inFunc, xValues));
Error in solve (line 8)
x = genGuess(inFunc, varargin{1}, varargin{2});
Error in makeSolveFunc>#(func)solve(func,start,stop) (line 3)
sFunc = #(func) solve(func, start, stop);
But, the first input IS a function handle. Also... if I manually apply the function to each element of the provided cell array, everything works fine:
>> solveFunc(equArray{1})
ans =
4.7335
>> solveFunc(equArray{2})
ans =
4.7356
Does anyone know why this would be happening? I assumed that if I could manually apply the function to each element of my array, and the return type of the function was consistent and one of the allowed types (you can't for example have arrayfun return an array of function handles... I already tried doing that), it should work. Perhaps that is not the only requirement.
Here is some code that generates this error:
solve.m
function solution = solve(inFunc, start, stop)
%SOLVE solve an equation using Newton's Method
x = genGuess(inFunc, start, stop);
for i = 1:100
m = getSlope(inFunc, x);
x = (m*x - inFunc(x))/m;
end
solution = x;
end
function slope = getSlope(inFunc, x)
%SLOPE calculate the slope at a given point
inc = 1e-5;
if x ~= 0
inc = inc * x;
end
slope = (inFunc(x + inc) - inFunc(x - inc))/(2*inc);
end
function guess = genGuess(inFunc, start, stop)
%GENGUESS get an initial guess to the solution
xValues = linspace(start, stop, 101);
funcVals = abs(arrayfun(inFunc, xValues));
[~, minIndex] = min(funcVals);
guess = xValues(minIndex);
end
charEqu.m
function equ = charEqu(a)
%CHAREQU create a KP model characteristic equation with provided p
equ = #(x) x + a;
end
makeSolveFunc.m
function sFunc = makeSolveFunc(start, stop)
%MAKESOLVEFUNC return a function that solves an equation
sFunc = #(func) solve(func, start, stop);
end
test.m
pArray = 1:5;
equArray = cell(1,arrayLen);
for i = 1:5
equArray{i} = charEqu(pArray(i));
end
solveFunc = makeSolveFunc(1.1*pi, 2*pi);
alphaAArray = arrayfun(solveFunc, equArray);
I have narrowed down the error to something in genGuess(). For some reason, in the line funcVals = abs(arrayfun(inFunc, xValues)); the variable inFunc is a 1x1 cell array containing a function handle. I have no idea why that would be the case. I traced this back to the anonymous function call #(func) solve(func, start, stop); in the makeSolveFunc() function. There it is still a 1x1 cell array containing a function handle. I'm not really sure where that cell array is coming from as that function is getting called from arrayfun().
Background information on what I'm trying to do in case someone wants to suggest a better way:
I'm trying to solve equations using Newton's method. I have written a function that can solve an equation given an initial guess range. This function is the solve() function you can see in the first error message. It takes a function, and the guess range and returns a function that I'm calling solveFunc(). solveFunc() takes a function and solves it using the initial guess range previously provided.
Maybe I'm just too used to functional programming and should just use a loop.
If the arguments passed to the function handle are contents of elements of a cell array, you need to use cellfun instead of arrayfun:
cellfun(solveFunc, equArray)
This is equivalent to
for i=1:length(equArray)
out(i) = solveFunc(equArray{i});
end
since solveFunc is already a function handle.
Check where the error comes from. This line causes the error:
funcVals = abs(arrayfun(inFunc, xValues));
The first input argument is a 1x1 cell containing one function handle. This is caused because equArray is a cell, thus use cellfun as Jonas already mentioned:
pArray = 1:5;
equArray = cell(1,arrayLen);
for i = 1:5
equArray{i} = charEqu(pArray(i));
end
solveFunc = makeSolveFunc(1.1*pi, 2*pi);
alphaAArray = cellfun(solveFunc, equArray);

Matlab function return value

I have one program that has function and the problem, return value, it has too many output.
Like exempley: y = text the answer comes up
Error in text (line 2)
if nargin == 0
Output argument "array" (and maybe others) not assigned during call to "
C:\Users\name\Documents\MATLAB\text.m>text".
The program text.m reads a txt file that contains a couple of names and numbers like
exemple:
John doughlas 15986
Filip duch 357852
and so on. The program convert them to 15986 Doughlas John and so on.
function array = text(~)
if nargin == 0
dirr = '.';
end
answer = dir(dirr);
k=1;
while k <= length(answer)
if answer(k).isdir
answer(k)=[];
else
filename{k}=answer(k).name;
k=k+1;
end
end
chose=menu( 'choose file',filename);
namn = char(filename(chose));
fid = fopen(namn, 'r');
R = textscan(fid,'%s %s %s');
x=-1;
k=0;
while x <= 24
x = k + 1;
All = [R{3}{x},' ',R{1}{x},' ',R{2}{x}];
disp(All)
k = k + 1;
end
fclose(fid);
Is there anyway to fix the problem without starting over from scratch?
Grateful for all the answers!
You specify the function output argument in the definition, but you don't assign anything to it in the function body.
For example, in
function y = student(j)
your output is y. So you have to assign something to y.
Read more about functions in MATLAB.
Here is a working example.
The first part is to create a function called 'functionA' in a filename 'functionA.m'. Then put the following code inside:
function result = functionA(N,alpha)
result = 5;
return
end
The second part is to create another Matlab file(i.e. upto you to name it) or you can use the Matlab command window even. Then run the following code:
getresult = functionA(100,10);
getresult
After running you get the following answer:
ans =
5

feval error nlfilter, reference to a cleared variable

Here is a part of a function I am trying for testing a larger function.
function funct(subfn)
clear all; % this is now removed
clc;
I = rand(11,11);
ld = input('Enter the lag = ') % prompt for lag distance
A = nlfilter(I, [7 7], str2func(subfn));
% Subfunction
function [h] = dirvar(I)
c = (size(I)+1)/2
EW = I(c(1),c(2):end)
h = length(EW) - ld
end
% Subfunction
function [h] = diagvar(I)
c = (size(I)+1)/2
NE = diag(I(c(1):-1:1,c(2):end))
h = length(NE) - ld
end
end
If I remove the clear all statement, then the following error appears,
Enter the lag = 1
ld =
1
??? Error using ==> feval
Undefined function or method 'dirvar' for input arguments of type 'double'.
Error in ==> nlfilter at 61
b = mkconstarray(class(feval(fun,aa(1+rows,1+cols),params{:})), 0, size(a));
Error in ==> funct at 5
A = nlfilter(I, [7 7], str2func(subfn));
Please ignore this part as I have now removed clear all statement as suggested in an answer below.
When I run funct('dirvar') I am greeted with this error:
Enter the lag = 1
ld =
1
??? Reference to a cleared variable subfn.
Error in ==> funct at 6
A = nlfilter(I, [7 7], str2func(subfn));
What might be the reason?
Do NOT (i.e. never) put clear all inside a function. subfn is defined as the function is called, clear all removes this definition. Remember that a function has its own workspace, which is different from the base workspace seen by the command line. Thus, all that clear all can do for you is make a mess.
EDIT
Since STR2FUNC doesn't allow you to construct function handles from nested functions, you may want to use a switch/case block to select your function, i.e.
function funct(subfn)
%# construct the right handle
switch subfn
case 'dirvar'
subfn = #dirvar;
case 'diagvar'
subfn = #diagvar;
otherwise
error('subfunction %s not defined',subfn)
end
I = rand(11,11);
ld = input('Enter the lag = ') % prompt for lag distance
A = nlfilter(I, [7 7], subfn);
Your clear all statement clears the input parameter to the function, 'subfn'. This is the expected behavior.
According to the str2func docs, "Nested functions are not accessible to str2func. To construct a function handle for a nested function, you must use the function handle constructor, #."