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

 採用された回答

Matt J
Matt J 2021 年 9 月 30 日
編集済み: Matt J 2021 年 9 月 30 日

0 投票

In order for solve() to find a solution, an exact analytical solution must exist.

9 件のコメント

Minerva Bionic
Minerva Bionic 2021 年 9 月 30 日
Is there a method other than solve() that can solve these equations?
Matt J
Matt J 2021 年 9 月 30 日
編集済み: Matt J 2021 年 9 月 30 日
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
Matt J
Matt J 2021 年 9 月 30 日
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
Minerva Bionic
Minerva Bionic 2021 年 9 月 30 日
編集済み: Minerva Bionic 2021 年 9 月 30 日
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 = 
Matt J
Matt J 2021 年 9 月 30 日
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.
Minerva Bionic
Minerva Bionic 2021 年 9 月 30 日
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.
Matt J
Matt J 2021 年 9 月 30 日
編集済み: Matt J 2021 年 9 月 30 日
You mean aside from lsqnonlin and vpasolve? But we've shown that they work. What would an additional suggestion give you?
Minerva Bionic
Minerva Bionic 2021 年 9 月 30 日
編集済み: Minerva Bionic 2021 年 9 月 30 日
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.
Minerva Bionic
Minerva Bionic 2021 年 9 月 30 日
編集済み: Minerva Bionic 2021 年 9 月 30 日
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 = 

サインインしてコメントする。

その他の回答 (0 件)

製品

リリース

R2020a

質問済み:

2021 年 9 月 30 日

編集済み:

2021 年 9 月 30 日

Community Treasure Hunt

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

Start Hunting!

Translated by