How to figure out eigenvalues of a matrix in matlab when all entries of matrix are variables? - matlab

I have a matrix with a bunch of unknown constants such as the one below:
a*b -c -d 0
-c e -a -b-d
-d -a d -e
0 -b-d -e a
As you may realize it is symmetric about the diagonal and therefore, the diagonal values are all positive. All constants are greater than 0.
I would like to solve this for the eigenvalues in matlab. How would I go about doing this? I do not know the values a,b,c,d, and e. I would like to do something like this:
d = eig(#getMatrix)
but the eig function does not accept function handles.

No problem in MATLAB.
>> syms a b c d e
>> M = [a*b -c -d 0
-c e -a -b-d
-d -a d -e
0 -b-d -e a];
>> eig(M)
ans =
a/4 + d/4 + e/4 + (a*b)/4 - ((51*a*d^3)/16 - (117*a^4*b)/16 + (27*a^3*d)/16 + (27*a*e^3)/16 + (57*b*d^3)/2 + (27*a^3*e)/16 + (27*d*e^3)/16 + (51*d^3*e)/16 + 6*((4*(2*b*d - (a*e)/4 - (a*d)/4 - (d*e)/4 - (a^2*b)/4 + (11*a^2)/8 + b^2 + c^2 + (19*d^2)/8 + (11*e^2)/8 + (3*a^2*b^2)/8 - (a*b*d)/4 - (a*b*e)/4)*((17*a*d^3)/64 - (39*a^4*b)/64 + (9*a^3*d)/64 + (9*a*e^3)/64 + (19*b*d^3)/8 + (9*a^3*e)/64 + (9*d*e^3)/64 + (17*d^3*e)/64 + (45*a^4)/256 + (285*d^4)/256 + (45*e^4)/256 - (a^2*b^2)/16 + (a^2*b^3)/8 + (3*a^2*b^4)/16 + (31*a^4*b^2)/128 + (a^4*b^3)/64 - (3*a^4*b^4)/256 + (3*a^2*c^2)/16 + (15*a^2*d^2)/128 - (9*a^2*e^2)/128 + (19*b^2*d^2)/16 - (b^2*e^2)/16 + (3*c^2*d^2)/16 + (15*c^2*e^2)/16 +
...
(a*b*c^2*e)/8 + (3*a*b*d*e^2)/64 + (11*a*b*d^2*e)/64 + (a*b^2*d*e)/4 - (33*a^2*b*d*e)/32 - (5*a^2*b^2*d*e)/64 + (a*b*d*e)/4 + (a*c*d*e)/2 - 2*b*c*d*e) - 256*((17*a*d^3)/64 - (39*a^4*b)/64 + (9*a^3*d)/64 + (9*a*e^3)/64 + (19*b*d^3)/8 + (9*a^3*e)/64 + (9*d*e^3)/64 + (17*d^3*e)/64 + (45*a^4)/256 + (285*d^4)/256 + (45*e^4)/256 - (a^2*b^2)/16 + (a^2*b^3)/8 + (3*a^2*b^4)/16 + (31*a^4*b^2)/128 + (a^4*b^3)/64 - (3*a^4*b^4)/256 + (3*a^2*c^2)/16 + (15*a^2*d^2)/128 - (9*a^2*e^2)/128 + (19*b^2*d^2)/16 - (b^2*e^2)/16 + (3*c^2*d^2)/16 + (15*c^2*e^2)/16 + (15*d^2*e^2)/1...
Output truncated. Text exceeds maximum line length of 25,000 characters for Command Window display.
I deleted a lot there. Admittedly, its rather messy and lengthy, but can you really expect better?
Edit: I should comment that such a long extended formula may be dangerous in terms of computational accuracy. I've seen people blindly use such a mess of an expression, evaluating it in Fortran or MATLAB. They think that because it is "symbolic" that it is also exact. This is a total fallacy when numerical computations are done.
There may well be immense subtractive cancellation in those terms, with huge positive and negative terms almost canceling each other out, leaving a tiny result that is essentially worthless because of the limited dynamic range of floating point computations. BEWARE. At the very least, compare single and double precision computations done with the same expression. If they differ by any significant amount, try an extended precision version to verify there is not a problem for the doubles. If you have not tested such an expression and verified it extensively, don't trust it.

Related

Matrix with symbolic math gives a symbolic answer, not a numeric one

Consider the following matrix
Ja(t1, t2, t3, t4, t5, t6) =
[ (sin(t5)*(cos(t3)*cos(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)) - sin(t3)*sin(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))))/5 - sin(t1)/100 - (219*sin(t1)*sin(t2))/1000 - (19*cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/100 - (21*cos(t3)*cos(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/1000 + (21*sin(t3)*sin(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/1000, (219*cos(t1)*cos(t2))/1000 + (sin(t5)*(cos(t3)*cos(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)) - sin(t3)*sin(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))))/5 - (19*cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/100 - (21*cos(t3)*cos(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/1000 + (21*sin(t3)*sin(t4)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/1000, (sin(t5)*(cos(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)) + cos(t4)*sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))))/5 - (19*sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/100 - (21*cos(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/1000 - (21*cos(t4)*sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/1000, (sin(t5)*(cos(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)) + cos(t4)*sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))))/5 - (21*cos(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/1000 - (21*cos(t4)*sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/1000, -(cos(t5)*(cos(t3)*cos(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)) - sin(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))))/5, 0]
[ cos(t1)/100 + (219*cos(t1)*sin(t2))/1000 + (29*cos(t1)*sin(t3))/1000 - (21*cos(t4)*(cos(t1)*sin(t3) - cos(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))))/1000 - (21*sin(t4)*(cos(t1)*cos(t3) + sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))))/1000 + (sin(t5)*(cos(t4)*(cos(t1)*sin(t3) - cos(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))) + sin(t4)*(cos(t1)*cos(t3) + sin(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))))/5 + (19*cos(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/100, (219*cos(t2)*sin(t1))/1000 - (sin(t5)*(cos(t3)*cos(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)) - sin(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2))))/5 + (19*cos(t3)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/100 + (21*cos(t3)*cos(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/1000 - (21*sin(t3)*sin(t4)*(cos(t1)*cos(t2) - sin(t1)*sin(t2)))/1000, (29*cos(t3)*sin(t1))/1000 - (21*cos(t4)*(cos(t3)*sin(t1) + sin(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))))/1000 + (21*sin(t4)*(sin(t1)*sin(t3) - cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))))/1000 - (19*sin(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))/100 + (sin(t5)*(cos(t4)*(cos(t3)*sin(t1) + sin(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))) - sin(t4)*(sin(t1)*sin(t3) - cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))))/5, (21*sin(t4)*(sin(t1)*sin(t3) - cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))))/1000 - (21*cos(t4)*(cos(t3)*sin(t1) + sin(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))))/1000 + (sin(t5)*(cos(t4)*(cos(t3)*sin(t1) + sin(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))) - sin(t4)*(sin(t1)*sin(t3) - cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))))/5, (cos(t5)*(cos(t4)*(sin(t1)*sin(t3) - cos(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1))) + sin(t4)*(cos(t3)*sin(t1) + sin(t3)*(cos(t1)*sin(t2) + cos(t2)*sin(t1)))))/5, 0]
[ 0, 0, (21*cos(t3)*cos(t4))/1000 - (29*cos(t3))/1000 - (21*sin(t3)*sin(t4))/1000 - (sin(t5)*(cos(t3)*cos(t4) - sin(t3)*sin(t4)))/5, (21*cos(t3)*cos(t4))/1000 - (21*sin(t3)*sin(t4))/1000 - (sin(t5)*(cos(t3)*cos(t4) - sin(t3)*sin(t4)))/5, -(cos(t5)*(cos(t3)*sin(t4) + cos(t4)*sin(t3)))/5, 0]
The problem is that when I put my arguments, MATLAB doesn't calculate the matrix numerically, rather it leaves it symbolically.
This is the result:
Ja(q(1),q(2),q(3),q(4),q(5),q(6)) =
[ sin(63/100)/100 + (219*sin(528276371951843/1125899906842624)*sin(63/100))/1000 + (19*cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/100 + (sin(59/125)*(cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)) - sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))))/5 + (21*cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/1000 - (21*sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/1000, (219*cos(528276371951843/1125899906842624)*cos(63/100))/1000 + (19*cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/100 + (sin(59/125)*(cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)) - sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))))/5 + (21*cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/1000 - (21*sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/1000, - (19*sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/100 - (sin(59/125)*(cos(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)) + cos(157/250)*sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))))/5 - (21*cos(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/1000 - (21*cos(157/250)*sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/1000, - (sin(59/125)*(cos(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)) + cos(157/250)*sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))))/5 - (21*cos(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/1000 - (21*cos(157/250)*sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/1000, -(cos(59/125)*(cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)) - sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))))/5, 0]
[ cos(63/100)/100 + (219*sin(528276371951843/1125899906842624)*cos(63/100))/1000 + (29*cos(63/100)*sin(157/125))/1000 + (19*cos(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/100 - (21*cos(157/250)*(cos(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))))/1000 - (sin(59/125)*(cos(157/250)*(cos(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))) + sin(157/250)*(cos(63/100)*cos(157/125) + sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))))/5 - (21*sin(157/250)*(cos(63/100)*cos(157/125) + sin(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))))/1000, (19*cos(157/125)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/100 - (219*cos(528276371951843/1125899906842624)*sin(63/100))/1000 + (sin(59/125)*(cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)) - sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100))))/5 + (21*cos(157/125)*cos(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/1000 - (21*sin(157/125)*sin(157/250)*(cos(528276371951843/1125899906842624)*cos(63/100) + sin(528276371951843/1125899906842624)*sin(63/100)))/1000, (19*sin(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))/100 - (29*cos(157/125)*sin(63/100))/1000 + (21*cos(157/250)*(cos(157/125)*sin(63/100) + sin(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))))/1000 - (21*sin(157/250)*(sin(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))))/1000 + (sin(59/125)*(cos(157/250)*(cos(157/125)*sin(63/100) + sin(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))) - sin(157/250)*(sin(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))))/5, (21*cos(157/250)*(cos(157/125)*sin(63/100) + sin(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))))/1000 - (21*sin(157/250)*(sin(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))))/1000 + (sin(59/125)*(cos(157/250)*(cos(157/125)*sin(63/100) + sin(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))) - sin(157/250)*(sin(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))))/5, -(cos(59/125)*(cos(157/250)*(sin(63/100)*sin(157/125) - cos(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100))) + sin(157/250)*(cos(157/125)*sin(63/100) + sin(157/125)*(cos(528276371951843/1125899906842624)*sin(63/100) - sin(528276371951843/1125899906842624)*cos(63/100)))))/5, 0]
[ 0, 0, (21*cos(157/125)*cos(157/250))/1000 - (29*cos(157/125))/1000 - (21*sin(157/125)*sin(157/250))/1000 + (sin(59/125)*(cos(157/125)*cos(157/250) - sin(157/125)*sin(157/250)))/5, (21*cos(157/125)*cos(157/250))/1000 - (21*sin(157/125)*sin(157/250))/1000 + (sin(59/125)*(cos(157/125)*cos(157/250) - sin(157/125)*sin(157/250)))/5, -(cos(59/125)*(cos(157/125)*sin(157/250) + cos(157/250)*sin(157/125)))/5, 0]
Is there a way I can get real numbers ?
Short answer: evaluate your symbolic expression numerically using eval or convert it to a specific type using one of these options, f.e. double or vpa.
Note that eval may be twice as slow as using double, but is sometimes slightly faster too
Explanation
The problem is that MATLAB does not evaluate your symbolic expression numerically, it only simplifies your expression mathematically.
Example:
syms x
my_function(x) = cos(x)
% exact algebraic solution is known:
my_function(0) % returns 1
my_function(pi) % returns -1
my_function(pi/2) % returns 0
my_function(pi/6) % returns 3^(1/2)/2
% result can only be numerically approximated:
my_function(3.1415) % returns cos(6283/2000)
my_function(1) % returns cos(1)
So, MATLAB is able to simplify the cos expression when the result is exactly known. In general, the result of cos can only be numerically evaluated, therefore MATLAB displays cos in it answer.
If you want a numerical result you can use one of the following options:
eval: evaluates your matrix numerically
double: converts to double precision
single: converts to single precision
int8 : converts to 8 bit integers (alternatives int16, int32, int64)
vpa: converts to variable-precision arithmetic, i.e. it allows you to specify the desired accuracy (number of significant digits) of the result
See Conversion Between Symbolic and Numeric for more information
Is using eval a good option?
As pointed out by Sardar Usama, using eval (to evaluate a string) is often bad practice:
Evading eval.
Alternatives to the eval Function
But, is this the same eval?
No, I don't think so. help sym/eval returns (in contrast to help eval):
eval Evaluate a symbolic expression.
eval(S) evaluates the character representation of the
symbolic expression S in the caller's workspace.
Also using the MATLAB debugger points out that it is a different function. However, the full explanation mentions that it evaluates the character representation of the expression, which can also be seen in the source code:
s = evalin('caller',vectorize(map2mat(char(x))));
So, it uses internally evalin, which is similar to eval, to evaluate a string. This may not be very efficient.
So, we should avoid sym/eval too?
Maybe not, also double uses eval internally to evaluate a string:
Xstr = mupadmex('symobj::double', S.s, 0);
X = eval(Xstr);
The difference is that sym/eval uses eval (evalin) for the original character representation, i.e. the whole expression, whereas double uses it to parse the final result, i.e. the numerically evaluated value.
Conclusion: for your example double seems to be the appropriate method as it is twice as fast as using eval. However, for the following example eval is somewhat faster (~15%):
my_function(x) = cos(x);
for i=2:100
my_function(x) = my_function(x) + cos(i*x);
end

Clarification on bias of a perceptron

Isn't it true that if a bias is not present, a line passing through origin should be able to linearly separate the two data sets??
But the most popular answer in this -->> question says
y
^
| - + \\ +
| - +\\ + +
| - - \\ +
| - - + \\ +
---------------------> x
stuck like this
I am confused about it. Do you mean the origins in figure above are somewhere in middle of x-axis and y-axis? Can somebody please help me and clarify this?
Alright, so perhaps the original ASCII graph was not 100% accurate! Let me try to depict this again:
y y
^ ^
- + \\ | + -\\+ | +
- +\\ | + + - \\ + | + +
- - \\ | + - - \\ | +
- - + \\| + - - \\+ | +
------------------------> x ---------------------------> x
- - |\\ + - - \\ | +
- - + | \\ + - - \\ + | +
- - - | \\ + + - - -\\ | + +
-- - - | +\\ ++ -- - - \\ | + ++
stuck like this needs to get like this
y = ax y = ax + b
(w0*x + w1*y = 0) (w0*x + w1*y + w2*1 = 0)
I think your intuition is correct on this issue:
Do you mean the origins in figure above are somewhere in middle of x-axis and y-axis?
In my reading of the graph, yes.
I think the ASCII graph, as cool as it is, is a bit confusing here, because it shows a line that is not traveling through what would normally be considered as the origin. Normally one would think of the intersection of the x- and y-axis lines as the origin, but in this diagram the separating line is clearly not passing through said intersection. As you've noted, a perceptron without a bias term can only define a separating line that passes through the origin, so the ASCII graph must have some sort of odd origin that is floating out in space somewhere.
Also, note that a standard perceptron always defines a linear separator, but a linear separator is not guaranteed to be able to partition a given dataset correctly -- that depends completely on the dataset. There are also variants of the perceptron that use the "kernel trick" to define nonlinear separators, but that's a whole different story. :)
Hope that helps.

Solve constrained equation with 2 variables

EDIT:
I think what I need is to apply fmincon, but I don't know how. I want to do this:
Use fmincon to solve:
Minimize a, subject to the equality constraint
f(q,z) = 0
by varying the unknowns (q,z).
How do I use fmincon to implement this? Thanks!
Here is the entire function:
f(q,z) = 60*q^9*z^4 + 120*q^7*z^3 + 80*q^(17/2)*z^3 - 60*q^8*z^3 - 60*q^6*z^3 + 40*q^(15/2)*z^3 + 20*q^(11/2)*z^3 - 20*q^9*z^3 + 175*q^(13/2)*z^2 - 90*q^(15/2)*z^2 + 75*q^5*z^2 - 60*q^6*z^2 - 45*q^(11/2)*z^2 + 40*q^2*z^2 + 30*q^8*z^2 - 30*q^(3/2)*z^2 - 10*q^(17/2)*z^2 + 15*q^(9/2)*z^2 - 20*q^4*z^2 - 10*q^(7/2)*z^2 - 90*q^(11/2)*z + 86*q^(9/2)*z + 75*q^6*z - 45*q^(7/2)*z + 40*q^(3/2)*z - 30*q^7*z - 20*q^(13/2)*z - 24*q^(1/2)*z + 15*q^4*z + 15*q^3*z - 9*q^(5/2)*z - 9*q^5*z + 45*q^4 - 30*q^5 + 30*q^(1/2) - 29*q^3 + 21*q^(5/2) - 10*q^(9/2) - 9*q^2 - 24.
----- original post -------
I have a function of 2 variables q and z like
f(q,z) = 60*q^9*z^4 + 120*q^7*z^3 + 80*q^(17/2)*z^3 - 60*q^8*z^3 - 60*q^6*z^3 + ...
I need to find
f(q,z) = 0
with respect to z, but this is not possible analytically (resulting in RootOf). So instead of finding all points, I want to numerically find the smallest number z such that the value pair (q,z) fulfills f(q,z) = 0. Any ideas how to do this?
I'm afraid there is no minimum z, as f(q,z) = 0: q↓0 ⇒ z↓-∞.
Your original equation can be written as:
Writing all the terms following like powers of z as A, B, C, D and E, you basically have
This is a quartic equation in z, which can definitely be solved analytically. Granted, it's a bit awkward, but possible nonetheless.
Note that the fact that A = f(q), B = g(q), C = h(q), D = k(q) and E = m(q) does not matter, as your goal is to express z = F(q).
Here's one way to find the minimum z for which f(q,z)=0 holds:
function find_minimum_z
solution = fminsearch(#F, 3)
end
function R = F(q)
R = roots([
60.*q.^9
120.*q.^7 + 80.*q.^(17/2) - 60.*q.^8 - 60.*q.^6 + 40.*q.^(15/2) + 20.*q.^(11/2) - 20.*q.^9
175.*q.^(13/2) - 90.*q.^(15/2) + 75.*q.^5 - 60.*q.^6 - 45.*q.^(11/2) + 40.*q.^2 + 30.*q.^8 - 30.*q.^(3/2) - 10.*q.^(17/2) + 15.*q.^(9/2) - 20.*q.^4 - 10.*q.^(7/2)
-90.*q.^(11/2) + 86.*q.^(9/2) + 75.*q.^6 - 45.*q.^(7/2) + 40.*q.^(3/2) - 30.*q.^7 - 20.*q.^(13/2) - 24.*q.^(1/2) + 15.*q.^4 + 15.*q.^3 - 9.*q.^(5/2) - 9.*q.^5
45.*q.^4 - 30.*q.^5 + 30.*q.^(1/2) - 29.*q.^3 + 21.*q.^(5/2) - 10.*q.^(9/2) - 9.*q.^2 - 24
]);
R = min(R(imag(R)==0));
if isempty(R)
R = NaN; end
end
My trials indicate there is an asymptote at q=0 for which the minimum, real z that solves the quartic tends to -∞.
Indeed this is what you can see when you make a plot of F(q):
If all terms after the first term have a z³, then it's really quite simple:
f(q,z) = 60q⁹z⁴ + 120q⁷z³ + 80q¹⁷/²z³ - 60q⁸z³ - 60q⁶z³ + ...
= z⁴·(60q⁹) + z³·(120q⁷ + 80q¹⁷/² - 60q⁸ - 60q⁶ + ... )
f(q,z) = 0
⇒ z⁴ · (60q⁹) = -z³ · (120q⁷ + 80q¹⁷/² - 60q⁸ - 60q⁶ + ...)
⇒ -z · (60q⁹) = 120q⁷ + 80q¹⁷/² - 60q⁸ - 60q⁶ + ...
⇒ z = -(120q⁷ + 80q¹⁷/² - 60q⁸ - 60q⁶ + ...) / 60q⁹
= -(2q⁷ + 1⅓q¹⁷/² - q⁸ - q⁶ + ...) / q⁹

Finding all solutions to a non-linear equation system with MuPAD

My question is if there is a good way to use MuPAD functions in a Matlab script. The background is that I have a problem where I need to find all solutions to a set of non-linear equations. The previous solution was to use solve in Matlab, which works for some of my simulations (i.e., some of the sets of input T) but not always. So instead I'm using MuPAD in the following way:
function ut1 = testMupadSolver(T)
% # Input T should be a vector of 15 elements
mupadCommand = ['numeric::polysysroots({' eq1(T) ' = 0,' ...
eq2(T) '= 0},[u, v])'];
allSolutions = evalin(symengine, mupadCommand);
ut1 = allSolutions;
end
function strEq = eq1(T)
sT = #(x) ['(' num2str(T(x)) ')'];
strEq = [ '-' sT(13) '*u^4 + (4*' sT(15) '-2*' sT(10) '-' sT(11) '*v)*u^3 + (3*' ...
sT(13) '-3*' sT(6) '+v*(3*' sT(14) '-2*' sT(7) ')-' sT(8) '*v^2)*u^2 + (2*' ...
sT(10) '-4*' sT(1) '+v*(2*' sT(11) '-3*' sT(2) ')+v^2*(2*' sT(12) ' - 2*' ...
sT(3) ')-' sT(4) '*v^3)*u + v*(' sT(7) '+' sT(8) '*v+' sT(9) '*v^2)+' sT(6)];
end
function strEq = eq2(T)
sT = #(x) ['(' num2str(T(x)) ')'];
strEq = ['(' sT(14) '-' sT(13) '*v)*u^3 + u^2*' '(' sT(11) '+(2*' sT(12) '-2*' sT(10) ...
')*v-' sT(11) '*v^2) + u*(' sT(7) '+v*(2*' sT(8) '-3*' sT(6) ')+v^2*(3*' sT(9) ...
'-2*' sT(7) ') - ' sT(8) '*v^3) + v*(2*' sT(3) '-4*' sT(1) '+v*(3*' sT(4) ...
'-3*' sT(2) ')+v^2*(4*' sT(5) ' - 2*' sT(3) ')-' sT(4) '*v^3)+' sT(2)];
end
I have two queries:
1) In order to use MuPAD I need to rewrite my two equations for the equation-system as strings, as you can see above. Is there a better way to do this, preferably without the string step?
2) And regarding the format output; when
T = [0 0 0 0 0 0 0 0 0 0 1 0 1 0 1];
the output is:
testMupadSolver(T)
ans =
matrix([[u], [v]]) in {matrix([[4.4780323328249527319374854327354], [0.21316518769990291263811232040432]]), matrix([[- 0.31088044854742790561428736573347 - 0.67937835289645431373983117422178*i], [1.1103383836576028262792542770062 + 0.39498445715599777249947213893789*i]]), matrix([[- 0.31088044854742790561428736573347 + 0.67937835289645431373983117422178*i], [1.1103383836576028262792542770062 - 0.39498445715599777249947213893789*i]]), matrix([[0.47897094942962218512261248590261], [-1.26776233072168360314707025141]]), matrix([[-0.83524238515971910583152318717102], [-0.66607962429342496204955062300669]])} union solvelib::VectorImageSet(matrix([[0], [z]]), z, C_)
Can MuPAD give the solutions as a set of vectors or similarly? In order to use the answer above I need to sort out the solutions from that string-set of solutions. Is there a clever way to do this? My solution so far is to find the signs I know will be present in the solution, such as '([[' and pick the numbers following, which is really ugly, and if the solution for some reason looks a little bit different than the cases I've covered it doesn't work.
EDIT
When I'm using the solution suggested in the answer below by #horchler, I get the same solution as with my previous implementation. But for some cases (not all) it takes much longer time. Eg. for the T below the solution suggested below takes more than a minute whilst using evalin (my previous implementation) takes one second.
T = [2.4336 1.4309 0.5471 0.0934 9.5838 -0.1013 -0.2573 2.4830 ...
36.5464 0.4898 -0.5383 61.5723 1.7637 36.0816 11.8262]
The new function:
function ut1 = testMupadSolver(T)
% # Input T should be a vector of 15 elements
allSolutions = feval(symengine,'numeric::polysysroots', ...
[eq1(T),eq2(T)],'[u,v]');
end
function eq = eq1(T)
syms u v
eq = -T(13)*u^4 + (4*T(15) - 2*T(10) - T(11)*v)*u^3 + (3*T(13) - 3*T(6) ...
+ v*(3*T(14) -2*T(7)) - T(8)*v^2)*u^2 + (2*T(10) - 4*T(1) + v*(2*T(11) ...
- 3*T(2)) + v^2*(2*T(12) - 2*T(3)) - T(4)*v^3)*u + v*(T(7) + T(8)*v ...
+ T(9)*v^2) + T(6);
end
function eq = eq2(T)
syms u v
eq = (T(14) - T(13)*v)*u^3 + u^2*(T(11) + (2*T(12) - 2*T(10))*v ...
- T(11)*v^2) + u*(T(7) + v*(2*T(8) - 3*T(6) ) + v^2*(3*T(9) - 2*T(7)) ...
- T(8)*v^3) + v*(2*T(3) - 4*T(1) + v*(3*T(4) - 3*T(2)) + v^2*(4*T(5) ...
- 2*T(3)) - T(4)*v^3) + T(2);
end
Is there a good reason to why it takes so much longer time?
Firstly, Matlab communicates with MuPAD via string commands so ultimately there is no way of getting around the use of strings. And because it's the native format, if you're passing large amounts of data into MuPAD, the best approach will be to convert everything to strings fast and efficiently (sprintf is usually best). However, in your case, I think that you can use feval instead of evalin which allows you to pass in regular Matlab datatypes (under the hood sym/feval does the string conversion and calls evalin). This method is discussed in this MathWorks article. The following code could be used:
T = [0 0 0 0 0 0 0 0 0 0 1 0 1 0 1];
syms u v;
eq1 = -T(13)*u^4 + (4*T(15) - 2*T(10) - T(11)*v)*u^3 + (3*T(13) - 3*T(6) ...
+ v*(3*T(14) -2*T(7)) - T(8)*v^2)*u^2 + (2*T(10) - 4*T(1) + v*(2*T(11) ...
- 3*T(2)) + v^2*(2*T(12) - 2*T(3)) - T(4)*v^3)*u + v*(T(7) + T(8)*v ...
+ T(9)*v^2) + T(6);
eq2 = (T(14) - T(13)*v)*u^3 + u^2*(T(11) + (2*T(12) - 2*T(10))*v ...
- T(11)*v^2) + u*(T(7) + v*(2*T(8) - 3*T(6) ) + v^2*(3*T(9) - 2*T(7)) ...
- T(8)*v^3) + v*(2*T(3) - 4*T(1) + v*(3*T(4) - 3*T(2)) + v^2*(4*T(5) ...
- 2*T(3)) - T(4)*v^3) + T(2);
allSolutions = feval(symengine, 'numeric::polysysroots',[eq1,eq2],'[u,v]');
The last argument still needed to be a string (or omitted) and adding ==0 to the equations also doesn't work, but the zero is implicit anyways.
For the second question, the result returned by numeric::polysysroots is very inconvenient and not easy to work with. It's a set (DOM_SET) of matrices. I tried using coerce to convert the result to something else to no avail. I think you best bet it to convert the output to a string (using char) and parse the result. I do this for simpler output formats. I'm not sure if it will be helpful, but feel free to look at my sym2float which just handles symbolic matrices (the 'matrix([[ ... ]])' part go your output) using a few optimizations.
A last thing. Is there a reason your helper function includes superfluous parentheses? This seems sufficient
sT = #(x)num2str(T(x),17);
or
sT = #(x)sprintf('%.17g',T(x));
Note that num2str only converts to four decimal places by default. int2str (or %d should be used if T(x) is always an integer).

Multiplying out negated terms in boolean algebra?

I'm just learning boolean algebra at the moment. I read that for XOR we can rearrange the expression
(A + B) . ¬(A + B)
= A.¬A + A.¬B + B.¬A + B.¬B
= A.¬B + B.¬A
I can understand this but I'm unsure how I would proceed multiplying out an expression like
(A + B) . (¬A + ¬B).
If I just try and naively multiply out all the terms that will bring me to the same result as XOR but the truth table is different. What are the rules on multiplying out negated terms?
Your first expression isn't an xor, try making this substitution: Z = A+B
You can throw this kinda thing at Wolfram Alpha. Here's what I did:
http://www.wolframalpha.com/input/?i=truth+table+(a+or+b)+and+(not+a+or+not+b)
Please click on the link to view the results! Does that truth table look like what you thought it should, or not?
You think the truth table is different?
Try evaluating it yourself.
You need DeMorgan's Law
Answers here are not clear to me. I believe there's a typo in how you typed #1. It is a contradiction:
(A + B) * -(A + B)
(A + B) * -A * -B
-A * -B * A + -A * -B * B
0
If #1 were (A + B) * (-A + -B) instead:
(A + B) * (-A + -B)
-A * (A + B) + -B * (A + B)
-A * A + -A * B + -B * A + -B * B
-A * B + -B * A
That's how you distribute AND over OR.