Error using minus in MATLAB - matlab

temp(i,1) = rand(1)*(pb(1,num).pos(i,1) - pw(1,num).pos(i,1));
This line gives the following error:
Error using ==> minus
Not enough input arguments.
The following are the definitions of pb and pw.
pw=struct('fitness',[],'pos',{});
pb=struct('fitness',[],'pos',{});
pos is a 2 x 1 array.

When tracking down errors like this, I break the problem up into smaller bits. Especially when the logic isn't readily apparent. Not only does it provide a path that can be used to step through your function using the debugger, but it also makes it more readable.
I've taken liberty with the intermediate variable names.
thisPb = pb(1,num);
thisPw = pw(1,num);
initialPos= pw.pos(i,1);
finalPos = pb.pos(i,1);
whos initialPos finalPos
temp(i,1) = rand(1) * (finalPos - initialPos);
The line with whos will print out the values. Make sure that finalPos and initialPos are both numbers.

One way that you can get this error is when num is an empty matrix.

The expression
>> s(x).a
can return a variable number of outputs, depending on the size of x.
If x = [1,2,3] for example, it will return three values (as long as s has at least three elements).
If x = [] on the other hand, then s(x).a will return no outputs, so the expression
>> disp(s(x).a)
will give you a Not enough input arguments error, which is almost certainly what you're seeing. You should check that num is not empty.

Are you sure, that all values are really initialised? Try to check this before your codeline.
disp(pb(1,num).pos(i,1))
disp(pw(1,num).pos(i,1))
temp(i,1) = rand(1)*(pb(1,num).pos(i,1) - pw(1,num).pos(i,1));

Related

Create array of tf objects in Matlab

If I wanted to create an array of specified class I would use an approach like this. So creating an array of int looks like this:
Aint = int16.empty(5,0);
Aint(1) = 3;
And it works fine. Now I want to create an array of tf class objects. My approach was similar:
L = tf.empty(5, 0);
s = tf('s');
L(1) = s;
This gives me an error:
Error using InputOutputModel/subsasgn (line 57)
Not enough input arguments.
Error in tf_array (line 6)
L(1) = s;
I also made sure to display class(s) and it correctly says it's tf. What do I do wrong here?
As usual, the MATLAB documentation has an example for how to do this sort of thing:
sys = tf(zeros(1,1,3));
s = tf('s');
for k = 1:3
sys(:,:,k) = k/(s^2+s+k);
end
So, the problem likely is that the indexing L(1) is wrong, it needs to be L(:,:,1).
Do note that tf.empty(5, 0) is instructing to create a 5x0 array (i.e. an empty array). There is no point to this. You might as well just skip this instruction. Because when you later do L(:,:,1), you'll be increasing the array size any way (it starts with 0 elements, you want to assign a new element, it needs to reallocate the array). You should always strive to create the arrays of the right size from the start.

How to Give int-string-int Input as Parameter for Matlab's Matrix?

I would like to have short-hand form about many parameters which I just need to keep fixed in Matlab 2016a because I need them in many places, causing many errors in managing them separately.
Code where the signal is 15x60x3 in dimensions
signal( 1:1 + windowWidth/4, 1:1 + windowWidth,: );
Its pseudocode
videoParams = 1:1 + windowWidth/4, 1:1 + windowWidth,: ;
signal( videoParams );
where you cannot write videoParams as string but should I think write ":" as string and everything else as integers.
There should be some way to do the pseudocode.
Output of 1:size(signal,3) is 3 so it gives 1:3. I do not get it how this would replace : in the pseudocode.
Extension for horcler's code as function
function videoParams = fix(k, windowWidth)
videoParams = {k:k + windowWidth/4, k:k + windowWidth};
end
Test call signal( fix(1,windowWidth){:}, : ) but still unsuccessful giving the error
()-indexing must appear last in an index expression.
so I am not sure if such a function is possible.
How can you make such a int-string-int input for the matrix?
This can be accomplished via comma-separated lists:
signal = rand(15,60,3); % Create random data
windowWidth = 2;
videoParams = {1:1+windowWidth/4, 1:1+windowWidth, 1:size(signal,3)};
Then use the comma-separated list as such:
signal(videoParams{:})
which is equivalent to
signal(1:1+windowWidth/4, 1:1+windowWidth, 1:size(signal,3))
or
signal(1:1+windowWidth/4, 1:1+windowWidth, :)
The colon operator by itself is shorthand for the entirety of a dimension. However, it is only applicable in a direct context. The following is meaningless (and invalid code) as the enclosing cell has no defined size for its third element:
videoParams = {1:1+windowWidth/4, 1:1+windowWidth, :};
To work around this, you could of course use:
videoParams = {1:1+windowWidth/4, 1:1+windowWidth};
signal(videoParams{:},:)

If and elseif, only the first line work?

L=1; Nx=51; PeriodicFlag=1; T=15; Nt=51;
spacedef='Pade6FirstDeriv'; casedef='LinearAdvection';
if (spacedef == 'Pade6FirstDeriv')
D1 = sparse(Pade6(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Upwind3FirstDeriv')
D1 = sparse(Upwind3(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Central4FirstDeriv')
D1 = sparse(Central4(Nx,dx,PeriodicFlag));
elseif (spacedef == 'Central2FirstDeriv')
D1 = sparse(Central2(Nx,dx,PeriodicFlag));
else
error(sprintf('Unknown spacedef = %s',spacedef));
end
In the above code, the if section is a small segment from a function I've constructed. I'm trying to get the function to know which methods to use based on my input (spacedef). Central2, Central4, Upwind3, and Pade6 are other functions I've written. The weird thing is that when spacedef =/= to 'Pade6FirstDeriv', I would get an error stating Error using ==, Matrix dimensions must agree. I've tried swapping the order of the if loop (by placing Central4, Central2, Pade6, and Upwind3 in the first line of the loop), and it seems like only the top line of the loop will work (the elseifs are not working). I'd greatly appreciate it if anybody can help me out. Thanks!
As has been noted in the comments, this is a common error when people first start comparing strings in MATLAB, and strcmp or strcmpi is generally the solution.
However, one solution the questions links in the comments don't present, and a solution I think looks much nicer, is the switch statement:
switch (spacedef)
case('Pade6FirstDeriv')
D1 = sparse(Pade6(Nx,dx,PeriodicFlag));
case('Upwind3FirstDeriv')
D1 = sparse(Upwind3(Nx,dx,PeriodicFlag));
case('Central4FirstDeriv')
D1 = sparse(Central4(Nx,dx,PeriodicFlag));
case('Central2FirstDeriv')
D1 = sparse(Central2(Nx,dx,PeriodicFlag));
otherwise
error(sprintf('Unknown spacedef = %s',spacedef));
end
Note: if I expect others to use my code with string comparisons, I usually lower the input such that the comparison is case-insensitive, although I have not done that here.

going from command window (as script) to function

the program is working perfectly but when i am changing it to function the follwing error is beeing displayed:
[Parent1index, Parent1Position, alldcel] = Parent1n(TotalnoOfGrids, noOfNodes, Penalties, test)
??? Index exceeds matrix dimensions.
Error in ==> Parent1n at 10
[~,index]=min(alldcel{t});
Because alldcell{t} may not exist for some values of t if the condition to assign values to it in
if Penalties{t}(r)== 0;
alldcel{t}(r)=inf;
end
is never satisfied. Assume for some t that all values of Penalties{t} are different than zero. Then you would never assign inf to alldcell{t}. That means, you are only extending the cell array alldcell when Penalties{t} is zero for some r. If the condition is never satisfied, alldcell{t} will not exist and asking for it will give you a cell array error.
You should at least initialize it using alldcell = cell(TotalnoOfGrids,1).
Also, comparing for equality to zero using a==0 is not a good idea. You should use abs(a)<tol for some small value tol.
ok with this code the functiion worked:if Penalties{t}(r)> 0;
alldcel {t}(r)=alldcel{t}(r);
else alldcel {t}(r)=inf; but interchanging if statement with else did not

How can I count the number of properties in a structure in MATLAB?

I have a function that returns one or more variables, but as it changes (depending on whether the function is successful or not), the following does NOT work:
[resultA, resultB, resultC, resultD, resultE, resultF] = func(somevars);
This will sometimes return an error, varargout{2} not defined, since only the first variable resultA is actually given a value when the function fails. Instead I put all the output in one variable:
output = func(somevars);
However, the variables are defined as properties of a struct, meaning I have to access them with output.A. This is not a problem in itself, but I need to count the number of properties to determine if I got the proper result.
I tried length(output), numel(output) and size(output) to no avail, so if anyone has a clever way of doing this I would be very grateful.
length(fieldnames(output))
There's probably a better way, but I can't think of it.
It looks like Matthews answer is the best for your problem:
nFields = numel(fieldnames(output));
There's one caveat which probably doesn't apply for your situation but may be interesting to know nonetheless: even if a structure field is empty, FIELDNAMES will still return the name of that field. For example:
>> s.a = 5;
>> s.b = [1 2 3];
>> s.c = [];
>> fieldnames(s)
ans =
'a'
'b'
'c'
If you are interested in knowing the number of fields that are not empty, you could use either STRUCTFUN:
nFields = sum(~structfun(#isempty,s));
or a combination of STRUCT2CELL and CELLFUN:
nFields = sum(~cellfun('isempty',struct2cell(s)));
Both of the above return an answer of 2, whereas:
nFields = numel(fieldnames(s));
returns 3.