非线性方程(组):MATLAB内置函数 solve, vpasolve, fsolve, fzero, roots [MATLAB]

您所在的位置:网站首页 燃放烟花爆竹的安全教案 非线性方程(组):MATLAB内置函数 solve, vpasolve, fsolve, fzero, roots [MATLAB]

非线性方程(组):MATLAB内置函数 solve, vpasolve, fsolve, fzero, roots [MATLAB]

2024-01-07 01:34| 来源: 网络整理| 查看: 265

MATLAB函数 solve, vpasolve, fsolve, fzero, roots 功能和信息概览

求解函数 多项式型 非多项式型 一维 高维 符号 数值 算法 solve 支持,得到全部符号解 若可符号解则得到根 支持 支持 支持 当无符号解时

 符号解方法:利用等式性质得到标准可解函数的方法

基本即模拟人工运算

vpasolve 支持,得到全部数值解 (随机初值)得到一个实根 支持 支持 $\times$ 支持 未知 fsolve 由初值得到一个实根 由初值得到一个实根 支持 支持 $\times$  支持

 优化方法,即用优化方法求解函数距离零点最近,具体方法为信赖域方法。

包含预处理共轭梯度(PCG)、狗腿(dogleg)算法和Levenberg-Marquardt算法等

fzero 由初值得到一个实根 由初值得到一个实根 支持 $\times$  $\times$  支持

一维解非线性方程方法,二分法、二次反插和割线法的混合运用

具体原理见数值求解非线性方程的二分法、不动点迭代和牛顿法和插值方法 

roots 支持,得到全部数值解 $\times$ 支持 $\times$ $\times$  支持

特征值方法,即将多项式转化友矩阵(companion matrix)

然后使用求矩阵特征值的算法求得所有解(那是另外一个问题了)

 

   也就是说,之前写了几篇关于非线性求解的,如二分法、牛顿法(参见二分法、不动点迭代、牛顿法)、二次反插法(参见插值法),只有一个库函数用了类似的方法。

各函数用法详解

1. (符号/数值)解方程(组)函数 solve

  官方参考页:Equations and systems solver - MATLAB solve

  solve 是基本的用于符号解方程的内置函数,返回类型为符号变量矩阵($m\times n$ sym)。当无法符号求解时,抛出警告并输出一个数值解。基本形式为:

solve(eqn, var, Name, Val);  % eqn为符号表达式/符号变量/符号表达式的函数句柄, var为未知量; Name为附加要求,Val为其值

  可以用solve解一维方程。对于多项式,solve可以返回其所有值。

func1 = @(x)x^3 - 20*x^2 - 25*x + 500; % 创建函数句柄.句柄中的变量不属符号变量,不需要定义! syms x exp1; % 定义符号变量 x, exp1; exp1 = x^3 - 20*x^2 - 25*x + 500; % 符号表达式,包含符号变量. 符号变量必须先有上一行定义! solve(exp1 == 0, x) % 命令行输入a,传入一个包含符号表达式的等式,x为所要求的变量 solve(exp1, x) % 命令行输入b,传入一个符号表达式,函数默认求其零点 solve(func1(x), x) % 命令行输入c,传入参数func1(x)等价于传入了符号表达式,和输入b完全一样 solve(func1(x) == 0, x) % 命令行输入d,这句话和a完全一样 solve(func1, x) % 命令行输入e,传入参数func1,这是一个函数句柄,函数默认求其零点 ans = % 命令行输出,三个解,为3*1的符号向量。对以上五种输入输出都完全一样 -5 5 20

  对于不可符号求解的函数零点/方程解,solve抛出警告并返回一个数值解:

exp1 = atan(x) - x - 1; % 不可符号求零点的表达式 solve(exp1 == 0, x) % 命令行输入 % 命令行输出: 警告: Cannot solve symbolically. Returning a numeric approximation instead. ans = -2.132267725272885131625420696936

  值得注意的是,虽然称之为“数值解”,并且输出了一个位数非常多的小数,但查看数据类型发现ans的数据类型依然是符号变量。其实,如果是正常的double类型的变量,直接输出是不可能给出这么多位的。matlab里面默认打印精度是4位小数,可以用  format long  语句调整到15位小数,和机器精度基本持平。

  solve也可以求解方程组,此时输入的表达式epn和变量var为行向量(亲测列向量不可用):

exp1 = [x^2/9 + y^2/4 == 1, 2*x - 3*y == 0]; % 联立椭圆方程和直线方程 solution = solve(exp1, [x, y]); % 解方程组 % 命令行输出 solution = 包含以下字段的struct: x: [2*1 sym] y: [2*1 sym] % 这意味着x和y均有两个解。函数输出的solution是一个struct,访问方法和C语言访问struct成员一样: struct.x % 命令行输入 ans = % 命令行输出 (3*2^(1/2))/2 -(3*2^(1/2))/2

  可以看出,当solve给出符号解的时候,它是不会化简计算的。任何matlab的符号计算,包括四则运算、求导积分,都不具备化简/数值计算的功能。

  此外,solve函数还有一些选项可选,这使得符号求解名副其实,这才是solve的强大之处。运用solve函数,Name设定为'ReturnConditions',其值设定为true,表示要求solve函数输出详细信息。用这个方法我们可以得出一族解:

% 求解方程sin(x)=cos(x),我们知道这个方程有无穷多解 [solution, parameter, condition] = solve(sin(x)==cos(x), x, 'ReturnConditions', true); % 命令行输出 solution = pi/4 + pi*k % 得到一族解,以pi为周期 parameter = k % parameter输出的是构成解的参数(符号变量) condition = in(k, 'integer'); % condition表明parameter的条件,此处k为整数

  而一般地,对于多变量的多项式(组),当多项式数量不足以确定所有参数时,按照以上设定,solve函数可以解出几个变量关于其他变量的函数:

exp1 = [x^2/9 + y^2/4 + z^2 == 1, 2*x - 3*y == 0]; % 椭球面和平面方程联立,结果应为曲线而非点 solution = solve(exp1, [x, y],'ReturnConditions', true); % 要求解出其中x和y的表达式 solution.x % 命令行输入:访问solution结构体的x参数 ans = % 命令行输出:x关于z的表达式,是符号向量,可以通过索引solution.x(1)和solution.x(2)分别访问 (3*2^(1/2)*(-(z - 1)*(z + 1))^(1/2))/2 -(3*2^(1/2)*(-(z - 1)*(z + 1))^(1/2))/2 % 结构体还有参数parameters和conditions。此处没有新生成的参数,因此parameters和conditions没有意义 solution.parameters % 命令行输入 ans = Empty sym: 1-by-0 solution.conditions % 命令行输入 ans = TRUE TRUE

  在solve中,还可以使用  assume 函数来规定符号变量的性质(如整数、大于零、区间等等)。

 

2. 多初值的数值解方程(组)函数 vpasolve

  官方参考页:Solve equations numerically - MATLAB vpasolve

  vpasolve是一款数值解方程(组)的函数。输入一些个参数,返回符号型数值标量/向量(即以数值的形式显示但实际上还是符号变量)。它的基本使用方式是:

vpasolve(eqns, vars, init_guess, 'Random', randomvalue); % 方程(组)eqns,变量vars,初值点init_guess(可缺省,在random模式下可写区间),'Random'设置randomvalue(可缺省)

  它的输入、功能和输出都和solve相仿。方程组的输入同样为行向量,变量组的输入也一样。

  当输入一个可以定解的多项式方程(组)时,vpasolve将会直接给出方程的数值解;若多项式方程数量不足以确定所有的解,那么vpasolve将会给出以剩余变量表示的所求变量的函数,只是表达式的一部分(系数等)可能会以数值的形式呈现。注意,有理分式方程将会多项式化以后一样处理。对于这些方程,init_guess的值写了也没用。

exp1 = (x-1)*(x-2)/(x-3); % 分式方程 solution = vpasolve(exp1, x) % 命令行输入 solution = % 命令行输出,得到了全部解 1.0 2.0

  对于多元方程组,vpasolve的输出也是struct结构体,访问方法也和solve输出的struct一样。不同的是,vpasolve无法求出含参的解,即无法设定'ReturnConditions'选项。和solve类似,除了多项式方程和有理分式方程以外的任何方程,vpasolve都不会给出全部解。这样一看,似乎vpasolve只不过就是把solve的结果全部转化为数值形式,甚至许多solve的功能都不能满足。这样的想法当然不对,vpasolve也有其自身的优势,这来源于:

  A)可以设置初值进行数值求解。对于不可符号求解的方程,solve因为没有设定初值,可能无法搜索到合适的解。vpasolve则可以设置初值,从而可以进行后续解的搜索;B)可以随机取初值。我们都知道求解方程和最优化问题的初值选取非常玄学,而同样的初值最多只能有一个解。而结合循环等控制语句,利用vpasolve的随机初值功能可以让这一过程变得比较简单。比如可以写作初等函数的半整数阶Bessel(贝塞尔)函数,其零点有无穷多,但无法通过符号方法求解,在solve中会遇到很大的问题,但是用vpasolve设置合适的初值可以得到许多组临近初值的解。比如:

syms x; exp1 = sin(x)/x; exp1 = diff(exp1, x); % 对原函数求导,得到的函数零点和3/2阶贝塞尔函数的零点相同 % 命令行输入 solution = solve(exp1, x) % 命令行输出,每次得到的结果均一样,为一个很遥远的解 警告: Cannot solve symbolically. Returning a numeric approximation instead. solution = -227.76107684764829218924973598808 solution = vpasolve(exp1, x, 1) % 命令行输入 solution = % 命令行输出大概就是0 0.00000000000000000000000014187233415524662526214503949551 solution = vpasolve(exp1, x, 3) % 命令行输入 solution = % 命令行输出 4.4934094579090641753078809272803  

   另外,一些有限个解的方程,比如 $atanx=x/2$ ,我们已经知道它有解0,根据画图还可以确定在x>0和x



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3