Can you please tell me how to solve four transcendental equations of four unknowns? - matlab

I have tried solving 4 equations of 4 unknowns in MATLAB and Mathematica.
I used vpasolve for finding the unknowns in MATLAB. Here is the MATLAB code.
Y1 = 0.02;
l1 = 0.0172;
syms Y2 Y3 l2 l3;
lambda = [0.0713 0.0688 0.0665];
b1 = 0.1170;
b3 = 0.1252;
t2_1 = (2*pi/lambda(1))*l2;
t3_1 = (2*pi/lambda(1))*l3;
t2_3 = (2*pi/lambda(3))*l2;
t3_3 = (2*pi/lambda(3))*l3;
t1_1 = (2*pi/lambda(1))*l1;
t1_3 = (2*pi/lambda(3))*l1;
eq1 = 2*Y1*tan(t1_1)+Y2*tan(t2_1)+Y3*tan(t3_1)==0;
eq2 = 2*Y1*tan(t1_3)+Y2*tan(t2_3)+Y3*tan(t3_3)==0;
eq3 = b1== (t1_1*Y1)+(t2_1*(Y2/2)*((sec(t2_1)^2)/(sec(t1_1)^2)))+(t3_1*(Y3/2)*((sec(t3_1)^2)/(sec(t1_1)^2)));
eq4 = b3== (t1_3*Y1)+(t2_3*(Y2/2)*((sec(t2_3)^2)/(sec(t1_3)^2)))+(t3_3*(Y3/2)*((sec(t3_3)^2)/(sec(t1_3)^2)));
E=[eq1 eq2 eq3 eq4];
S=vpasolve(E,[Y2,Y3,l2,l3]);
For the same equations, I wrote the below code in Mathematica.
eqns = {2*Y1*Tan[t11]+Y2*Tan[t21]+Y3*Tan[t31]==0,
2*Y1*Tan[t13]+Y2*Tan[t23]+Y3*Tan[t33]==0,
t11*Y1 + t21*(Y2/2)*(Sec[t21]^2/Sec[t11]^2) + t31*(Y3/2)*(Sec[t31]^2/Sec[t11]^2)-b1==0,
t13*Y1 + t23*(Y2/2)*(Sec[t23]^2/Sec[t13]^2) + t33*(Y3/2)*(Sec[t33]^2/Sec[t13]^2)-b3==0};
NMinimize[Norm[Map[First, eqns]], {Y2,Y3,l2,l3}]
But both are giving me different solutions and those are not the required solutions. I suppose I should use some other function for solving the equations. Can anyone help me finding out how to solve these equations? Your help is highly appreciated. Thank you.
EDIT
If I use the below code for finding the roots, I'm able to find the solutions but I just want positive roots. I tried the code which you have mentioned for getting positive roots but its not working for this and I don't know why. Can you please check this once?
Y1=0.0125;l1=0.010563;lambda={0.0426,0.0401,0.0403,0.0423,0.0413}; b1 = 0.0804;
b3 = 0.0258;
t2_1 = (2*Pi/lambda[[1]])*l2;
t3_1 = (2*Pi/lambda[[1]])*l3;
t2_3 = (2*Pi/lambda[[5]])*l2;
t3_3 = (2*Pi/lambda[[5]])*l3;
t1_1 = (2*Pi/lambda[[1]])*l1;
t1_3 = (2*Pi/lambda[[5]])*l1;
eqns = {2*Y1*Tan[t11]+Y2*Tan[t21]+Y3*Tan[t31]==0,
2*Y1*Tan[t13]+Y2*Tan[t23]+Y3*Tan[t33]==0,
t11*Y1 + t21*(Y2/2)*(Sec[t21]^2/Sec[t11]^2) + t31*(Y3/2)*(Sec[t31]^2/Sec[t11]^2)-b1==0,
t13*Y1 + t23*(Y2/2)*(Sec[t23]^2/Sec[t13]^2) + t33*(Y3/2)*(Sec[t33]^2/Sec[t13]^2)-b3==0};

Try
Y1=0.02;l1=0.0172;lambda={0.0713,0.0688,0.0665};b1=0.1170;b3=0.1252;
t21=(2*Pi/lambda[[1]])*l2;t31=(2*Pi/lambda[[1]])*l3;t23=(2*Pi/lambda[[3]])*l2;
t33=(2*Pi/lambda[[3]])*l3;t11=(2*Pi/lambda[[1]])*l1;t13=(2*Pi/lambda[[3]])*l1;
eqns={2*Y1*Tan[t11]+Y2*Tan[t21]+Y3*Tan[t31]==0,
2*Y1*Tan[t13]+Y2*Tan[t23]+Y3*Tan[t33]==0,
t11*Y1+t21*(Y2/2)*(Sec[t21]^2/Sec[t11]^2)+t31*(Y3/2)*(Sec[t31]^2/Sec[t11]^2)-b1==0,
t13*Y1+t23*(Y2/2)*(Sec[t23]^2/Sec[t13]^2)+t33*(Y3/2)*(Sec[t33]^2/Sec[t13]^2)-b3==0};
tbl=Table[
{y2i,y3i,l2i,l3i}=RandomReal[{0,.2},4];
Quiet[root=Check[FindRoot[eqns,{{Y2,y2i,0,.2},{Y3,y3i,0,.2},{l2,l2i,0,.2},{l3,l3i,0,.2}}],False]];
If[root===False,Nothing,root]
,{256}];
roots=Sort[Map[{Y2,Y3,l2,l3}/.#&,tbl],Norm[#1]<Norm[#2]&]
If[roots=={},"It found no roots in that range using those coefficients",
Map[First,eqns]/.{Y2->roots[[1,1]],Y3->roots[[1,2]],l2->roots[[1,3]],l3->roots[[1,4]]}]
That will look for roots starting at 256 different random locations greater than, but near 0. The way I have written FindRoot this time it will stop if the search is outside the range 0,.2 You can change that range if needed.
Next your functions have many local minima that trap FindRoot. So it should discard all local minima found inside that range.
And I have hidden the warning messages, usually not a good idea to do.
Then it will Sort the roots to show those nearest 0 first.
If you want it to sort to show the results nearest some given value then I can modify the Sort to show those first, I just need to know where you want the roots nearest to.
And finally it substitutes the Y2,Y3,l2,l3 of the smallest root it found back into the four equations to demonstrate that the results are very very near zero and this is a real root instead of a local minima.
After trying that a few times I found one root at {0.0203704,0.0225972,0.0163842,0.0181147} and that looks very close to your required values if I swap Y2 and Y3 and swap l2 and l3. Is that perhaps the root that you are looking for?
If you need more then please tell me exactly what is needed.
Please check ALL this VERY carefully to make certain I have made no mistakes.

Related

finding the phase angle of a signal - solving a non-linear (trigonometric) system of equations

I'm trying to calculate the phase2 angle/value in the y2 equation of a signal given at a specific frequency if I know the other values. Is this possible? Example below: along with picture example:
y1=A1*cos*(2*pi*f1*t+phase1) we know A1,f1,t=1,phase1
y1=0.00720858*cos*(2*pi*6+6.33)
y2=A2*cos*(2*pi*f2*t+phase2) we know A2,f2,t=1, trying to find **phase2**
y2=.4*cos*(2*pi*6.4951+phase2)
y3=A3*cos*(2*pi*f3*t+phase3) we know A3,f3,t=1,phase3
y3=0.0135274*cos(2*pi*7+.786473)
I'm using maxima 13.04.2, octave 3.8.1.
I tried to solve the y2 equation for phase2 in maxima but it got rid of the cos function
kill(all);
A:A; phase:phase; solve(A*cos*(2*pi*t+phase)=0,phase);
the answer came back as phase=-2pi*t
Is this possible? or should I go about this another way?
Thanks
The weird result might stem from the fact that you multiply the cos function with what is supposed to be its argument (by the way, this is mathematically unsound). What you might want is to apply the cos function to the argument. To illustrate what I mean, compare:
A*cos*(2*pi*t+phase)
with:
A*cos(2*pi*t+phase)
On another hand, why not solve the equation pen-on-paper style?
y2 = A2×cos(2πf2t + φ2) ⇒
y2/A2 = cos(2πf2t + φ2) ⇒
arccos(y2/A2) = 2πf2t + φ2 ⇒
arccos(y2/A2) - 2πf2t = φ2
With the values that you provided:
A2 = 0.4, f2 = 6.4951, t = 1.
you can calculate the phase φ2 as function of your level y2 (left as exercise to you).

maxima multiple trigonometric equations

I'm trying to solve an equation using maxima 13.04.2 but the answer isn't what I expect.
Example:
y2=A2*cos(2*pi*f2*t+phase2) we know A2=.4,f2=6.4951,t=1, trying to find **phase2**
y2=.4*cos(2*pi*6.4951+phase2)
I tried to solve the y2 equation for phase2 in maxima but it got rid of the cos function
kill(all);
A:A; phase:phase; solve(A*cos(2*pi*f*t+phase)=0,phase);
The answer that came back was
I thought something like this was suppose to come back
y2 = A2×cos(2πf2t + φ2) ⇒
y2/A2 = cos(2πf2t + φ2) ⇒
arccos(y2/A2) = 2πf2t + φ2 ⇒
arccos(y2/A2) - 2πf2t = φ2
so I could then plug in the vales
A2 = 0.4, f2 = 6.4951, t = 1 and get the phase
Any ideas how to get maxima to get the correct format?
PS: Yes I know I can do it by hand but I have thousands of equations like this and I plan on using octave arrays to call maxima to solve them and bring the answers back into octave.
Well, it seems straightforward.
(%i1) e:A*cos(2*%pi*f*t + phi) = y;
(%o1) cos(2 %pi f t + phi) A = y
(%i2) solve (e, phi);
solve: using arc-trig functions to get a solution.
Some solutions will be lost.
y
(%o2) [phi = acos(-) - 2 %pi f t]
A
(%i3) subst ([A = 0.4, f = 6.4951, t = 1], %o2);
(%o3) [phi = acos(2.5 y) - 12.9902 %pi]
Couple of notes. (1) solve can solve this equation, which is good, but bear in mind that it is fairly limited in its capability, and you can probably make up other equations that it can't solve. There are some other options for solving equations in Maxima, but it general that is a weak area. (2) Maybe instead of switching back and forth between Maxima and Octave, you can just code equation %o2 in Octave and evaluate that for different values of the parameters.

Matlab: linear congruence solver that supports a non-prime modulus?

I'm working on some Matlab code to perform something called the Index Calculus attack on a given cryptosystem (this involves calculating discrete log values), and I've gotten it all done except for one small thing. I cant figure out (in Matlab) how to solve a linear system of congruences mod p, where p is not prime. Also, this system has more than one variable, so, unless I'm missing something, the Chinese remainder theorem wont work.
I asked a question on the mathematics stackexchange with more detail/formatted mathjax here. I solved the issue in my question at that link, and now I'm attempting to find a utility that will allow me to solve the system of congruences modulo a non-prime. I did find a suite that includes a solver supporting modular arithmetic, but the modulus must be prime (here). I also tried stepping through to modify it to work with non-primes, but whatever method is used doesn't work, because it requires all elements of the system have inverses modulo p.
I've looked into using the ability in Matlab to call MuPAD functions, but from my testing, the MuPAD function linsolve (which seemed to be the best candidate) doesn't support non-prime modulus values either. Additionally, I've verified with Maple that this system is solvable modulo my integer of interest (8), so it can be done.
To be more specific, this is the exact command I'm trying to run in MuPAD:
linsolve([0*x + 5*y + 4*z + q = 2946321, x + 7*y + 2*q = 5851213, 8*x + y + 2*q = 2563617, 10*x + 5*y + z = 10670279],[x,y,z,q], Domain = Dom::IntegerMod(8))
Error: expecting 'Domain=R', where R is a domain of category 'Cat::Field' [linsolve]
The same command returns correct values if I change the domain to IntegerMod(23) and IntegerMod(59407), so I believe 8 is unsuitable because it's not prime. Here is the output when I try the above command with each 23 and 59407 as my domain:
[x = 1 mod 23, y = 1 mod 23, z = 12 mod 23, q = 14 mod 23]
[x = 14087 mod 59407, y = 1 mod 59407, z = 14365 mod 59407, q = 37320 mod 59407]
These answers are correct- x, y, z, and q correspond to L1, L2, L3, and L4 in the system of congruences located at my Math.StackExchange link above.
I'm wondering if you tried to use sym/linsolve and sym/solve previously, but may have passed in numeric rather than symbolic values. For example, this returns nonsense in terms of what you're looking for:
A = [0 5 4 1;1 7 0 2;8 1 0 2;10 5 1 0];
b = [2946321;5851213;2563617;10670279];
s = mod(linsolve(A,b),8)
But if you convert the numeric values to symbolic integers, sym/linsolve will keep everything in terms of rational fractions. Then
s = mod(linsolve(sym(A),sym(b)),8)
returns the expected answer
s =
6
1
6
4
This just solves the system linear system using symbolic math as if it were a normal matrix. For large systems this can be expensive, but I'd imagine no more than using MuPAD's numeric::linsolve or linalg::matlinsolve. sym/mod should return the modulus of the numerator of each solution component. I believe that you will get an error if the modulus and the denominator are not at least coprime.
sym/solve can also be used to solve this in a similar manner:
L = sym('L',[4,1]);
[L1,L2,L3,L4] = solve(A*L==b);
s = mod([L1;L2;L3;L4],8)
A possible issue with using either sym/solve or sym/linsolve is that if there are multiple solutions to the linear congruence problem (as opposed to the linear system), this approach may not return all of them.
Finally, using the MuPAD function numlib::ichrem (chinese remainder theorem for integers), here's some code that attempts to obtain the complete solution:
A = [0 5 4 1;1 7 0 2;8 1 0 2;10 5 1 0];
b = [2946321;5851213;2563617;10670279];
m = 10930888;
mf = str2num(strrep(char(factor(sym(m))),'*',' '));
A = sym(A);
b = sym(b);
s = sym(zeros(length(b),length(mf)));
for i = 1:length(mf)
s(:,i) = mod(linsolve(A,b),mf(i));
end
mstr = ['[' sprintf('%d,',mf)];
mstr(end) = ']';
r = sym(zeros(length(b),1));
for i = 1:length(b)
sstr = char(s(i,:));
r(i) = feval(symengine,'numlib::ichrem',sstr(9:end-2),mstr);
end
check = isequal(mod(A*r,m),b)
I'm not sure if any of this is what you're looking for, but hopefully it might be helpful. I think that it might be a good idea to put in a enhancement/service request with the MathWorks so that MuPAD and the other solvers can handle systems better in the future.

Matlab: Finding two unknown constants/parameters in an equation

I've read up on fsolve and solve, and tried various methods of curve fitting/regression but I feel I need a bit of guidance here before I spend more time trying to make something work that might be the wrong approach.
I have a series of equations I am trying to fit to a data set (x) separately:
for example:
(a+b*c)*d = x
a*(1+b*c)*d = x
x = 1.9248
3.0137
4.0855
5.0097
5.7226
6.2064
6.4655
6.5108
6.3543
6.0065
c= 0.0200
0.2200
0.4200
0.6200
0.8200
1.0200
1.2200
1.4200
1.6200
1.8200
d = 1.2849
2.2245
3.6431
5.6553
8.3327
11.6542
15.4421
19.2852
22.4525
23.8003
I know c, d and x - they are observations. My unknowns are a and b, and should be constant.
I could do it manually for each x observation but there must be an automatic and far superior way or at least another approach.
Very grateful if I could receive some guidance. Thanks for the time!
Given your two example equations; let y=x./d, then
y = a+b*c
y = a+a*b*c
The first case is just a line, for which you can obtain a least squares fit (values for a and b) with polyfit(). In the second case, you can just say k=a*b (since these are both fitted anyway), then rewrite it as:
y = a+k*c
Which is exactly the same line as the first problem, except now b = k/a. In fact, b=b1/a is the solution to the second problem where b1 is the fit from the first problem. In short, to solve them both, you need one call to polyfit() and a couple of divisions.
Will that work for you?
I see two different equations to fit here. To spell out the code:
For (a+b*c)*d = x
p = polyfit(c, x./d, 1);
a = p(2);
b = p(1);
For a*(1+b*c)*d = x
p = polyfit(c, x./d, 1);
a = p(2);
b = p(1) / a;
No need for polyfit; this is just a linear least squares problem, which is best solved with MATLAB's slash operator:
>> ab = [ones(size(c)) c] \ (x./d)
ans =
1.411437211703194e+000 % 'a'
-7.329687661579296e-001 % 'b'
Faster, cleaner, more educative :)
And, as Emmet already said, your second equation is nothing more than a different form of your first equation, the difference being that the b in your first equation, is equal to a*b in your second one.

Using fminsearch to solve an equation

(vgb-phy_s)^2=G^2*phy_t*((exp(-x)+x-1)+exp(-(2*phi_b/phi_t))*(exp(x)-x-1))
where
x=phy_s/phy_t
phy_t=0.0288; % phy_t=k*T/q; (k=1.3806503*10^-23, T=300 K, q=1.6*10^-19)
phy_b=0.5267; % phy_b=phy_t*ln(Na/ni)
G=(sqrt(2*q*es*Na)/cox);
Here I need to plot phy_s for different values of vgb.
I tried many ways but since I'm new to matlab I'm on my learning process, I'm not able to find a proper solution.
Few people suggested me to use fminsearch but its quite confusing and I'm getting lot of errors.
fminsearch is a function for finding a minimum of a function, not for finding a solution of an equation. Further, here you don't have one equation but an equation group of at least 5 equations. You can use solve to solve equations and equation groups. However, an equation group of the following equations 1-5 does not have explicit solution. Another issue is that the constant values you propose seem to be imprecise values, and if you have more than one rounded or otherwise imprecise value, you can not find a solution even if the equation group was solvable (however, this equation group does not have [an explicit] solution)).
So, I'll show the steps to solve this but there seems to be something wrong with this equation group, even if the [probably imprecise] constant definitions (phy_t=0.0288; phy_t=k*T/q; (k=1.3806503*10^-23; T=300; q=1.6*10^-19; phy_b=0.5267;`) were left out.
Equations (without constant definitions):
1. (vgb-phy_s)^2 = G^2*phy_t*((exp(-x)+x-1)+exp(-(2*phi_b/phi_t))*(exp(x)-x-1))
2. x = phy_s/phy_t
3. phy_t = k*T/q
4. phy_b=phy_t*ln(Na/ni)
5. G=(sqrt(2*q*es*Na)/cox)
To solve eg. equation group of equations 1, 2 & 3:
Solution = solve('(vgb-phy_s)^2 = G^2*phy_t*((exp(-x)+x-1)+exp(-(2*phi_b/phi_t))*(exp(x)-x-1))', 'x = phy_s/phy_t', 'phy_t = k*T/q');
Solution.q
ans =
(T*k)/phy_t
(T*k)/phy_t
Solution.vgb
ans =
phy_s + (G*phy_t^(1/2)*(exp((2*phi_b)/phi_t) - exp(phy_s/phy_t) + exp((2*phy_s)/phy_t) - exp((2*phi_b)/phi_t)*exp(phy_s/phy_t) - (phy_s*exp(phy_s/phy_t))/phy_t + (phy_s*exp((2*phi_b)/phi_t)*exp(phy_s/phy_t))/phy_t)^(1/2))/(exp((2*phi_b)/phi_t)^(1/2)*exp(phy_s/phy_t)^(1/2))
phy_s - (G*phy_t^(1/2)*(exp((2*phi_b)/phi_t) - exp(phy_s/phy_t) + exp((2*phy_s)/phy_t) - exp((2*phi_b)/phi_t)*exp(phy_s/phy_t) - (phy_s*exp(phy_s/phy_t))/phy_t + (phy_s*exp((2*phi_b)/phi_t)*exp(phy_s/phy_t))/phy_t)^(1/2))/(exp((2*phi_b)/phi_t)^(1/2)*exp(phy_s/phy_t)^(1/2))
Solution.x
ans =
phy_s/phy_t
phy_s/phy_t
Do note that this solution is valid only for equation group of equations 1-3. For example equation group of equations 1, 2, 4 or 1, 2, 5 gives a different solution.
To solve the equation group of all 5 equations you could use this:
Solution = solve('(vgb-phy_s)^2 = G^2*phy_t*((exp(-x)+x-1)+exp(-(2*phi_b/phi_t))*(exp(x)-x-1))', 'x = phy_s/phy_t', 'phy_t = k*T/q', 'phy_b = phy_t*ln(Na/ni)', 'G = sqrt(2*q*es*Na)/cox');
However, there is no solution:
Warning: Explicit solution could not be found.
In solve at 160
Solution =
[ empty sym ]
So, I suggest that you try to find out what is wrong with your equations and then try solve again with corrected equations.