Interpretation of # in a string argument to Matlab's quad - matlab

One of my students made the following simple error:
f = '#(x)sqrt(1-x^2)';
quad(f,0,1)
which led to a very unexpected (to me) result:
ans =
0 + 1.7119i
Presumably # is getting interpreted as some complex function, but which?

Related

eq returns true for non equal lists

I got a strange piece of code to debug which to my opinion should throw an exception but instead it produced totally odd results. Reduced it to these two lines:
EDU>> A={0,0}
A =
[0] [0]
EDU>> A{1:2}==A{2:1}
ans =
1
Why is the comparison of two non equal comma separated lists true?
The line of code A{1:2}==A{2:1} is not checking the equality of two comma-separated lists because 2:1 is an empty array. I think the intended indexing was 2:-1:1; this will create a comma-separated list but also throw an error since == cannot handle the list.
However, it is odd that A{1:2}==A{2:1} produces a valid output of any kind in my mind. The code is literally saying A{1:2} == A{[]}, and the question is "what is A{[]}?" According to my MATLAB R2014b, nothing, which makes some sense, but even a simple double array with an empty index returns an empty double. I guess the actual content, which is what is retreived by { and }, is nothing so, yeah.
But then how is MATLAB producing the answer of true?
Consider the following code from the command window:
>> A = {0,0}; A{1:2} == A{[]}
ans =
1
>> A = {0,1}; A{1:2} == A{[]}
ans =
0
From that, I surmise that MATLAB places the comma-separated list as the first two arguments to eq and appends A{[]} nothing to it and interpret it simply as
eq(0,0,A{[]})
eq(0,1,A{[]})
which is, apparently, valid syntax (eq(a,b,) is not). It is very interesting for a binary operation on elements of a cell array. This also works:
>> A = {[2,3],[3,2]};
>> A{1:2} .* A{[]}
ans =
6 6
>> A{1:2} ./ A{[]}
ans =
0.6667 1.5000
And just for fun, because I'm finding this quite interesting:
>> A = {rand(2),rand(2,1)};
>> A{1:2} \ A{[]}
ans =
0.8984
-0.7841
But I guess it makes sense. The parser finds a token, followed by an infix operator, followed by another token. It resolves the infix operator to its function, and then places the left and right tokens into the argument list in turn.
I guess I just find it a odd about the existence of "nothing"; although that would explain how [1,2,3,] is valid syntax.
That said, I'm sure this is a quirk of the language and not a bug nor a feature.
Of course, the only way to know what is actually going on is to have an intimate knowledge of how MATLAB is interpreting the cell array expansion and application of the operator. Of course, I do not have this experience nor the source required (I'd imagine).
Since both are 0. Try A = {1, 2} then you will get ans = 0

Error running matlab code after compiling

It looks like this has been asked many times, but none of the past posts seem to solve my question. All those had to do with matrix/vector while my code does not have any of these, just simple variables. It takes three variables as arguments. It works perfectly fine within the Matlab environment. I only got the error when I compiled it with mcc -m Normal.m and tried to run with the executable like this "./Normal 1 5 0.5". The complete error message is:
Error using /
Matrix dimensions must agree.
Error in Normal (line 4)
MATLAB:dimagree
It is complaining about line 4: N=2/dt, what is wrong with this?
Here is the code:
function val=Normal(l1,l2,dt)
const=(l2/l1-1);
N=2/dt;
S=1.0/sqrt(l2/l1);
Z(1)=S;
for i=2:N
t= -1+(i-1)*dt;
Z(i)=1.0/sqrt(const*t*t+1);
S=S+2*Z(i);
end
Z(21)=1.0/(l2/l1);
S=S+1.0/sqrt(l2/l1);
val=dt*S/2;
end
But dt is not a scalar when passed into the standalone through the command ./Normal 1 5 0.5. It is a character array with 3 elements ('0', '.','5')!
When passing numerical arguments to a standalone, they are passed as strings. Thus, inside the function, you need to convert '0.5' into a double, and similarly for l1 and l2:
dt = str2num(dt);
l1 = str2num(l1);
l2 = str2num(l2);
Note that you can use isdeployed to determine at runtime if the function is a standalone:
if isdeployed, dt = str2num(dt); end
And you might need to display the result:
if isdeployed, disp(val); end
Result:
>> system('Normal 1 5 0.5');
1.4307
>> Normal(1,5,0.5) % .m function for comparison
ans =
1.4307

Error using minus in 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));

x = disp(y) : "Too many output arguments"

I'm looking for a completely general way to convert any value to a string in MATLAB.
Basically, I want to be able to write something like
x = disp(y);
The above fails with the error Too many output arguments. (I was not able to find the source code for disp.)
Is there a single MATLAB function for converting any value into a string?
(Note that this function should behave like the identity when passed a string.)
Basically I'm looking for MATLAB's equivalent of Python's str. I thought it might be char, but (for example) char(Inf) fails to produce anything like the string 'Inf'. (Note: that was just an example. It does not begin to cover all the possibilities.)
pm89's answer has the right idea, but doesn't work because evalc requires a string as input. I suggest making your own function like so:
function str = anything2string(thing)
str = evalc('disp(thing)');
It works for anything that Matlab can display:
>> anything2string(3)
ans =
3
>> anything2string(Inf)
ans =
Inf
>> anything2string('hi')
ans =
hi
>> anything2string(1:4)
ans =
1 2 3 4
It's not quite the same as Python's str, but num2str works with Inf and handles strings as input.
num2str(Inf)
ans = Inf
num2str('some string')
ans = some string
You could get the exact same string as you see in your command window using evalc (evaluate and capture the result):
x = evalc('disp(y)'); % y could be anything displayable by Matlab!

MATLAB: If Statement inside loop is not executing, nor printing to the screen

So, we are trying to execute the following code. The two if statements are executing, however, the inside if statements are failing to execute (we verified this by not suppressing the output). Is there a reason why? Or are we just not able to reach this state?
Specifications
The input is as follows: v is a vector of int values and c is a integer. c must be less than or equal to one of the values within v
The problem that we are trying to solve with this algorithm is as follows:
Given a cash register, how does one make change such that the fewest coins
possible are returned to the customer?
Ex: Input: v = [1, 10, 25, 50], c = 40. Output O = [5, 1, 1, 0]
We are just looking for not a better solution but more of a reason why that portion of the code is not executing.
function O = changeGreedy(v,c)
O = zeros(size(v,1), size(v,2));
for v_item = 1:size(v,2)
%locate largest term
l_v_item = 1
for temp = 2:size(v,2)
if v(l_v_item) < v(temp)
l_v_item = temp
end
end
%"Items inside if statement are not executing"
if (c > v(l_v_item))
v(l_v_item) = -1 %"Not executing"
else
O(l_v_item) = idivide(c, v(l_v_item)) %"Not executing"
c = mod(c, v(l_v_item)) %"Not executing"
end
end
If c or v are not integers, i.e. class(c) evaluates to double, then I get the following error message
??? Error using ==> idivide>idivide_check at 66
At least one argument must belong to an integer class.
Error in ==> idivide at 42
idivide_check(a,b);
and the program stops executing. Thus, the inside of the second statement never executes. In contrast, if, say, c is an integer, for example of class uint8, everything executes just fine.
Also: what are you actually trying to achieve with this code?
Try to do this operation on your input data:
v = int32([1, 10, 25, 50]), c = int32(40)
and run again, at least some portions of your code will execute. There is an error raised by idivide, which apparently you missed:
??? Error using ==> idivide>idivide_check at 67
At least one argument must belong to an integer class.
Error in ==> idivide at 42
idivide_check(a,b);
Indeed, idivide seems to require that you have actual integer input data (that is, class(c) and class(v) both evaluate to an integer type, such as int32).