Symbolic Math Toolbox hitting divide by zero error when it used to evaluate to NaN - matlab

I've just updated to Matlab 2014a finally. I have loads of scripts that use the Symbolic Math Toolbox that used to work fine, but now hit the following error:
Error using mupadmex
Error in MuPAD command: Division by zero. [_power]
Evaluating: symobj::trysubs
I can't post my actual code here, but here is a simplified example:
syms f x y
f = x/y
results = double(subs(f, {'x','y'}, {1:10,-4:5}))
In my actual script I'm passing two 23x23 grids of values to a complicated function and I don't know in advance which of these values will result in the divide by zero. Everything I can find on Google just tells me not to attempt an evaluation that will result in the divide by zero. Not helpful! I used to get 'inf' (or 'NaN' - I can't specifically remember) for those it could not evaluate that I could easily filter for when I do the next steps on this data.
Does anyone know how to force Matlab 2014a back to that behaviour rather than throwing the error? Or am I doomed to running an older version of Matlab forever or going through the significant pain of changing my approach to this to avoid the divide by zero?

You could define a division which has the behaviour you want, this division function returns inf for division by zero:
mydiv=#(x,y)x/(dirac(y)+y)+dirac(y)
f = mydiv(x,y)
results = double(subs(f, {'x','y'}, {1:10,-4:5}))

Related

Matrix Multiplication Simplification not giving same results in code

I want to evaluate the expression xTAx -2yTAx+yTAy in Matlab.
If my calculations are correct, this should be equivalent to solving(x-y)TA(x-y)
My main problem right now is that I am not getting the same results from the above two expressions. I'm wondering if it's a precision error or a conceptual error.
I tried a very simple example with some random values to check my math was right. The mini example I used is as follows
A = [1,2,0;2,1,2;0,2,1];
x = [1;2;3];
y = [4;4;4];
(transpose(x)*A*x)-(2*transpose(y)*A*x)+(transpose(y)*A*(y))
transpose(x-y)*A*(x-y)
Both give 46.
I then tried a more realistic example of values for what I'm doing and it failed. For example
A = [2.66666666666667,-0.333333333333333,0,-0.333333333333333,-0.333333333333333,0,0,0,0;
-0.333333333333333,2.66666666666667,-0.333333333333333,-0.333333333333333,-0.333333333333333,-0.333333333333333,0,0,0;
0,-0.333333333333333,2.66666666666667,0,-0.333333333333333,-0.333333333333333,0,0,0;
-0.333333333333333,-0.333333333333333,0,2.66666666666667,-0.333333333333333,0,-0.333333333333333,-0.333333333333333,0;
-0.333333333333333,-0.333333333333333,-0.333333333333333,-0.333333333333333,2.66666666666667,-0.333333333333333,-0.333333333333333,-0.333333333333333 -0.333333333333333;
0,-0.333333333333333,-0.333333333333333,0,-0.333333333333333,2.66666666666667,0,-0.333333333333333,-0.333333333333333;
0,0,0,-0.333333333333333,-0.333333333333333,0,2.66666666666667,-0.333333333333333,0;
0,0,0,-0.333333333333333,-0.333333333333333,-0.333333333333333,-0.333333333333333,2.66666666666667,-0.333333333333333;
0,0,0,0,-0.333333333333333,-0.333333333333333,0,-0.333333333333333,2.66666666666667];
x =[1.21585420370805;
1.00388159497757e-16;
-0.405284734569351;
1.36809776609658e-16;
-1.04796659533634e-17;
-7.52459042423650e-17;
-0.607927101854027;
-8.49163704356314e-17;
0.303963550927013];
v =[0.0319067068305797,0.00786616506360615,0.0709811622828447,0.0719615328671117;
1.26150800194897e-17,5.77584497721720e-18,7.89740111567879e-18,7.14396333930938e-18;
-0.158358815125228,-0.876275686098803,0.0539216716399594,0.0450616819309899;
7.90937837037453e-18,3.24196519177793e-18,3.99402664932776e-18,4.17486202509670e-18;
5.35533279761622e-18,-8.91723780863019e-19,-1.56128480212603e-18,1.84423677629470e-19;
-2.18478057810330e-17,-6.63779320738873e-18,-3.21099714760257e-18,-3.93612240449303e-18;
-0.0213963226092681,-0.0168256143048771,-0.0175695110350900,-0.0128155908603601;
-4.06029341772399e-18,-5.65705978843172e-18,-1.80182480882056e-18,-1.59281757789645e-18;
0.221482525259710,-0.0576644539359728,0.0163934384910353,0.0197432976432437];
u = [1.37058079022968;
1.79302486419321;
69.4330887239959;
-52.3949662214410];
y = v*u;
Gives 0 for the first expression and 7.1387e-28 for the second. Is this a precision error thing? Which version is better/ more accurate to use and why? Thank you!
I have not checked your simplification, but floating-point math in general is inexact. Even doing the same operations in a different order can give you different results. With the deviations you are seeing I would believe they could reasonably come from inexactness in floating-point math and it is up to you to decide whether the deviations are acceptable for your purpose.
To determine which version is more accurate you would have to compute reference values to compare to, which might prove difficult.

Using mean function in MATLAB yielding different results [duplicate]

This question already has answers here:
Subscript indices must either be real positive integers or logicals, generic solution
(3 answers)
Closed 3 years ago.
I have just recently started using MATLAB as it's pretty good for machine learning and the like.
Currently, I am working on some type of classification which is pretty long-winded and complicated if I tried to explain everything I am trying to accomplish therefore I will just state the exact code giving me problems.
So, I am given a 1010 x 1764 single type matrix by some function. say the matrix is called train_examples_2_2 as you can see on the right-hand side of the screenshot below.
As you can also see from the screenshot above (on the right-hand side), the calls to mean and std:
mean = mean(train_examples_2_2)
std = std(train_examples_2_2)
Yield the correct results.
However, when I run the same code several times sometimes I get an error on the line mean = mean(train_examples_2_2) stating:
Array indices must be positive integers or logical values.
The exact code I am concerned with is:
mean = mean(train_examples_2_2) % <----- error appears here
std = std(train_examples_2_2)
for i=1:size(train_examples_2_2,1)
train_examples_2_2(i,:) = train_examples_2_2(i,:) - mean;
train_examples_2_2(i,:) = train_examples_2_2(i,:) ./ std;
end
% end of standardisation process
where train_examples_2_2 is provided by some function that I did not create nor can modify.
According to the MATLAB documentation:
If A is a matrix, then mean(A) returns a row vector containing the
mean of each column.
which is what I get the first time I run the code upon opening Matlab but after that, it yields the aforementioned error.
I am using MATLAB R2018b.
I'm I making a simple mistake or could this possibly be a bug?
Thanks for taking the time to help out.
unlike let's say python you shouldn't/can't/mussn't re-define function names or default variables.
mean = mean(train_examples_2_2) % <----- error appears here
matlab doesn't distinguish between the callable mean() function and the variable ```mean``. especially confusing since indexing and calling sth is done by using round brackets.
So....?
call your variable sth. other than mean. mean_ will already do the trick.

Matlab Symbolic Diff Fails

I'm working with the following code and I've run into a strange issue. If I do the following:
syms x n chebyprime(n,x)
chebyprime(n,x)=diff(chebyshevT(n,x),x);
The function outputs the expected result. But if I tweak it like this:
chebyprimeplus(n,x)=diff(chebyshevT(n+1,x),x)
It breaks the whole thing. Instead of a numeric output (Which would be expected of a derivative of a polynomial evaluated at a specific point) I get output like this:
>> chebyprimeplus(3,.2)
ans =
D([2], chebyshevT)(4, 1/5)
This is baffling behavior to me. It looks like it's outputting in some sort of mupad syntax, and I can't find any way to convert this to a numeric value. I don't see any reason simply upping the order of the chebyshev should cause the integration to fail and when I input a higher order by increasing the value of n it works fine so it's not an issue with the diff operator's ability to differentiate the chebyshev polynomial. Can anyone help me sort this out?
Thanks.

MATLAB: using a minimum function within symsum

I am trying to run code similar to the following, I replaced the function I had with one much smaller, to provide a minimum working example:
clear
syms k m
n=2;
symsum(symsum(k*m,m,0,min(k,n-k)),k,0,n)
I receive the following error message:
"Error using sym/min (line 86)
Input arguments must be convertible to floating-point numbers."
I think this means that the min function cannot be used with symbolic arguments. However, I was hoping that MATLAB would be substituting in actual numbers through its iterations of k=0:n.
Is there a way to get this to work? Any help much appreciated. So far I the most relevant page I found was here, but I am somewhat hesitant as I find it difficult to understand what this function does.
EDIT following #horchler, I messed around putting it in various places to try and make it work, and this one did:
clear
syms k m
n=2;
symsum(symsum(k*m,m,0,feval(symengine, 'min', k,n-k)),k,0,n)
Because I do not really understand this feval function, I was curious to whether there was a better, perhaps more commonly-used solution. Although it is a different function, there are many pieces online advising against the eval function, for example. I thought perhaps this one may also carry issues.
I agree that Matlab should be able to solve this as you expect, even though the documentation is clear that it won't.
Why the issue occurs
The problem is due the inner symbolic summation, and the min function itself, being evaluated first:
symsum(k*m,m,0,min(k,n-k))
In this case, the input arguments to sym/min are not "convertible to floating-point numbers" as k is a symbolic variable. It is only after you wrap the above in another symbolic summation that k becomes clearly defined and could conceivably be reduced to numbers, but the inner expression has already generated an error so it's too late.
I think that it's a poor choice for sym/min to return an error. Rather, it should just return itself. This is what the sym/int function does when it can't evaluate an integral symbolically or numerically. MuPAD (see below) and Mathematica 10 also do something like this as well for their min functions.
About the workaround
This directly calls a MuPAD's min function. Calling MuPAD functions from Matlab is discussed in more detail in this article from The MathWorks.
If you like, you can wrap it in a function or an anonymous function to make calling it cleaner, e.g.:
symmin = #(x,y)feval(symengine,'min',x,y);
Then, you code would simply be:
syms k m
n = 2;
symsum(symsum(k*m,m,0,symmin(k,n-k)),k,0,n)
If you look at the code for sym/min in the Symbolic Math toolbox (type edit sym/min in your Command Window), you'll see that it's based on a different function: symobj::maxmin. I don't know why it doesn't just call MuPAD's min, other than performance reasons perhaps. You might consider filing a service request with The MathWorks to ask about this issue.

sym2poly selectively working matlab

I'm evaluating a series of theoretical (not necessarily functional) circuits in matlab. I have been trying to get the transfer function of the circuits and during the process I use the sym2poly function. Sometimes, sym2poly works and returns the transfer function. Sometimes it does not.
This is what the code looks like:
[n,d] = numden(eval(v_3/V));
transH = tf(sym2poly(n),sym2poly(d))
n and d are symbolic cell arrays. The error I get is:
Error using sym/sym2poly (line 28)
Not a polynomial.
Error in CircuitGA (line 349)
n = sym2poly(n);
This looks similar to several questions posted a long time ago, but all of those were solved by a bug fix in an updated version of the symbolic math toolbox. Does it mean that what I am giving it is impossible to turn into a polynomial?
Is there a fix?
Any suggestions of a method that will work for all my circuit arrays?
Maybe a try and catch for if it can return a transfer function?