作者evanzxcv (铁扶龙)
看板MATLAB
标题Re: [问题] 联立方程式求解
时间Sat Apr 21 05:18:17 2007
※ 引述《pto2 (蔡少)》之铭言:
: 小弟我有小问题想请教各位先进,就是我有三个方程式分别为:
: a1*x+b1*y+c1*z+d1 = 0 ..............(1)
: a2*x^2+b2*y^2+c2*z^2+d2 = 0 ........(2)
: a3*x^2+b3*y^2+c3*z^2+d3 = 0 ........(3)
: 其中a1 a2 a3 b1 b2 b3 c1 c2 c3 d1 d2 d3 为常数
: 每次我用 solve 解就会当掉,请问有什麽好方法来求解这样的问题吗??
我写了个最佳化的程式solve1.m来解,需要猜一个起始值,
测试程式的结果是,起始值假如和解差太远(例如解是1,2,3,起始值猜一千之类的),
或方程组本身无实数解,就无法得解。
此程式只能用来解以上方程式系数都为实数的实数解,
假如系数有复数,或是需要复数解的话,可能要另外想办法了...
先解释程式中出现的代号好了,
输入的A,B是系数矩阵,X0是起始值,亦即:
A=[a1 b1 c1
a2 b2 c2
a3 b3 c3]
B=[d1
d2
d3]
X0=[x起始值
y起始值
z起始值]
输出的X是求得的近似解,sum是三个等式左边的平方和,亦即
X=[x
y
z]
sum=((1)式等号左方)^2+((2)式等号左方)^2+((3)式等号左方)^2
跑程式时把A,B,X0设好,然後直接用[X sum]=solve1(A,B,X0)来跑,
我选择把sum输出的原因是检验程式有没有跑成功,
假如sum很接近零就没错,假如sum很大的话,换个X0试试看吧!
至於程式里面的myfun是solve1的副函数,
他的目的是算出三个等式左方的平方和,因为系数和解都是实数,
平方一定大於等於零,因此把三个平方相加,所得的数值也大於等於零,
只要利用fminunc求最小值,那个最小值就是零了,就可以得到解。
myfun的输出中fun是三个等式左方的平方和,而grad是fun的梯度,
因为用梯度会让fminunc跑得更快(我测试的结果是一眨眼就好了)
%%%%%以下是程式solve1.m内容%%%%%
function [X sum] = solve1(A,B,X0)
options = optimset('GradObj','on','LargeScale','off','TolFun',eps,'TolX',eps);
[X sum] = fminunc(@(X) myfun(X,A,B), X0, options);
return
function [fun grad] = myfun(X,A,B)
sum1 = A(1,:)*X+B(1);
sum2 = A(2,:)*(X.^2)+B(2);
sum3 = A(3,:)*(X.^2)+B(3);
fun = sum1^2 + sum2^2 + sum3^2;
grad = zeros(3,1);
for i = 1:3,
grad(i) = 2*A(1,i)*sum1 + 4*A(2,i)*X(i)*sum2 + 4*A(3,i)*X(i)*sum3;
end
return
%%%%%程式结束%%%%%
不知道这样有没有解决原po的问题,
我是初学MATLAB的人啊,写的程式可能也不是很好...
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 128.42.158.2
※ 编辑: evanzxcv 来自: 128.42.158.26 (04/21 22:42)
1F:推 pto2:感谢~~我试试看 04/22 14:05