Problem with solving multivariable trigonometric equations

Hi everyone,
I have no idea where is wrong in my code?
clear all;
%%
clc
Fs = 1e6;
f = 5;
t = 2e6;
ang0 = t*2*pi*f/Fs
ang0 = 62.8319
dang = 1*2*pi*f/Fs
dang = 3.1416e-05
y0= 1*sin(t*2*pi*f/Fs);
y1= 1*sin((t+1)*2*pi*f/Fs);
y2= 1*sin((t+2)*2*pi*f/Fs);
% for i = 1:10e6
% Curve(i) = 1*sin(i*2*pi*f/Fs);
% end
%
% close all
% hold on
% plot(Curve)
%%
syms x y z
% assume(x > 0)
% assumeAlso(x < 1)
% assume(z >= 0)
% assumeAlso(z <= 2*pi)
% assume(y > 0)
% assumeAlso(y <= 100)
[x,y,z]=solve(x*sin((t*2*pi*y/Fs) + z)==y0 ,x*sin(((t+1)*2*pi*y/Fs)+z)==y1,x*sin(((t+2)*2*pi*y/Fs)+z)==y2,'ReturnConditions',true)
x = Empty sym: 0-by-1 y = Empty sym: 1-by-0 z = Empty sym: 0-by-1

 Accepted Answer

Matt J
Matt J on 30 Sep 2021
Edited: Matt J on 30 Sep 2021
In order for solve() to find a solution, an exact analytical solution must exist.

9 Comments

Is there a method other than solve() that can solve these equations?
With lsqnonlin, you can find an approximate solution:
[xyz,Error]=main()
Local minimum possible. lsqnonlin stopped because the final change in the sum of squares relative to its initial value is less than the value of the function tolerance.
xyz = 1×3
0.5187 3.1942 47.8254
Error = 8.8349e-10
function [xyz,Error]=main
Fs = 1e6;
f = 5;
t = 2e6;
ang0 = t*2*pi*f/Fs;
dang = 1*2*pi*f/Fs;
y0= 1*sin(t*2*pi*f/Fs);
y1= 1*sin((t+1)*2*pi*f/Fs);
y2= 1*sin((t+2)*2*pi*f/Fs);
fn=@(q) linspace(0,q,300);
[x,y,z]=ndgrid(fn(1),fn(2*pi),fn(100));
F1 = x.*sin((t.*2.*pi.*y/Fs) + z) - y0 ;
F2 = x.*sin(((t+1).*2.*pi.*y/Fs)+z) - y1 ;
F3 = x.*sin(((t+2).*2.*pi.*y/Fs)+z) - y2;
[fval,i0]=min(abs(F1)+abs(F2)+abs(F3),[],'all','linear');
X0=[x(i0), y(i0), z(i0)];
[xyz,Error]=lsqnonlin(@equations, X0,[0,0,0],[1,2*pi,100]);
function F=equations(X)
x=X(1); y=X(2); z=X(3);
F(1) = x.*sin((t.*2.*pi.*y/Fs) + z) - y0 ;
F(2) = x.*sin(((t+1).*2.*pi.*y/Fs)+z) - y1 ;
F(3) = x.*sin(((t+2).*2.*pi.*y/Fs)+z) - y2;
end
end
You can also use vpasolve()
Fs = 1e6;
f = 5;
t = 2e6;
ang0 = t*2*pi*f/Fs;
dang = 1*2*pi*f/Fs;
y0= 1*sin(t*2*pi*f/Fs);
y1= 1*sin((t+1)*2*pi*f/Fs);
y2= 1*sin((t+2)*2*pi*f/Fs);
%%
syms x y z
[x,y,z]=vpasolve(x*sin((t*2*pi*y/Fs) + z)==y0 ,...
x*sin(((t+1)*2*pi*y/Fs)+z)==y1,...
x*sin(((t+2)*2*pi*y/Fs)+z)==y2)
x = 
y = 
6.0380495220795251235306856371589
z = 
1221.6013978502790085715024981273
Thanks a lot.
But, why does it ignore assumptions when I add them?
Another thing; If I define 2 equations and declare y as 5 it can find the answer properly but when I declare y as a variable and define 3 equations it can not find proper answers (as you know proper answers are : x=1, y=5, z=0).
clear all;
%%
clc
Fs = 1e6;
f = 5;
t = 2e6;
y0= 1*sin(t*2*pi*f/Fs);
y1= 1*sin((t+1)*2*pi*f/Fs);
y2= 1*sin((t+2)*2*pi*f/Fs);
%%
syms x y z
assume(x > 0)
assumeAlso(x <= 1)
assume(z >= 0)
assumeAlso(z <= 2*pi)
assume(y > 0)
assumeAlso(y <= 10)
[x,y,z]=vpasolve(x*sin((t*2*pi*y/Fs) + z)==y0 ,...
x*sin(((t+1)*2*pi*y/Fs)+z)==y1 , ...
x*sin(((t+2)*2*pi*y/Fs)+z)==y2)
x = 
y = 
6.0380495220795251235306856371589
z = 
1221.6013978502790085715024981273
clear all;
%%
clc
Fs = 1e6;
f = 5;
t = 2e6;
y0= 1*sin(t*2*pi*f/Fs);
y1= 1*sin((t+1)*2*pi*f/Fs);
y2= 1*sin((t+2)*2*pi*f/Fs);
syms x z
assume(x > 0)
assumeAlso(x < 1)
assume(z >= 0)
assumeAlso(z <= 2*pi)
y = 5;
[x,z]=vpasolve(x*sin((t*2*pi*y/Fs) + z)==y0 ,...
x*sin(((t+1)*2*pi*y/Fs)+z)==y1)
x = 
1.0000000003041361573960955992907
z = 
as you know proper answers are : x=1, y=5, z=0
No, as you saw above with my lsqnonlin solution, other solutions are also possible.
But, why does it ignore assumptions when I add them?
According to the documentation, vpasolve ignores assumptions, but it does have a SpecifyRanges option
And, of course, lsqnonlin allows you to specify bounds, as I demonstrated for you.
Thank you Matt J.
I will look for different solutions.
However, it is appreciated if you could name other possible solutions that may work fine with my problem.
kind regards.
You mean aside from lsqnonlin and vpasolve? But we've shown that they work. What would an additional suggestion give you?
I know "least square nonlinear" and vpasolve methods are great in solving equations. But since I'm curious about another possible methods, I thought it would be fine if I ask you for other possible methods.
As I realized I should provide arrays of data for x, y, z for lsqnonlin method.
The solve method can return symbolic solutions. Since I want to implement the solution in a hardware, solve method is the best method in my case.
However, I still have problem with numerical vpasolve() method
clear all
clc
Fs = 1e6;
f = 5;
t = 2e6;
y0= 1*sin(t*2*pi*f/Fs);
y1= 1*sin((t+1)*2*pi*f/Fs);
y2= 1*sin((t+2)*2*pi*f/Fs);
% Available information for solving equations: y0,y1,y2, Fs, t
% Answers: x=1 , y=5, z=0
syms x y z
[x,y,z]=vpasolve(x*sin((t*2*pi*y/Fs) + z)==y0 ,...
x*sin(((t+1)*2*pi*y/Fs)+z)==y1 , ...
x*sin(((t+2)*2*pi*y/Fs)+z)==y2,[x y z],[0 1.2; 0 10; -pi pi])
x = 
0.82808197968524438542250921861996
y = 
6.0380495220795251235306856358895
z = 
%% Acceptable answers by reducing variables
clc
syms x z
y= 5;
[x,z] = vpasolve(x*sin((t*2*pi*y/Fs) + z)==y0 ,...
x*sin(((t+1)*2*pi*y/Fs)+z)==y1,[x z],[0 1.2; -pi pi])
x = 
1.0000000003041361573960955992907
z = 

Sign in to comment.

More Answers (0)

Products

Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!