solve, vpasolve, fsolve, fzero, roots等matlab函数的用法详解 </p><p><strong>MATLAB函数 solve, vpasolve, fsolve, fzero, roots 功能和信息概览</strong></p><p> </p><p> 也就是说,之前写了几篇关于非线性求解的,如二分法、牛顿法(参见二分法、不动点迭代、牛顿法)、二次反插法(参见插值法),只有一个库函数用了类似的方法。</p><p><strong>各函数用法详解</strong></p><p><strong>1. (符号/数值)解方程(组)函数 solve</strong></p><p> 官方参考页:Equations and systems solver - MATLAB solve</p><p> solve 是基本的用于符号解方程的内置函数,返回类型为符号变量矩阵($m imes n$ sym)。当无法符号求解时,抛出警告并输出一个数值解。基本形式为:</p><div></div><p> 可以用solve解一维方程。对于多项式,solve可以返回其所有值。</p><div></div><p> 对于不可符号求解的函数零点/方程解,solve抛出警告并返回一个数值解:</p><div></div><p>format long</p><p> solve也可以求解方程组,此时输入的表达式epn和变量var为行向量(亲测列向量不可用):</p><div></div><p> 可以看出,当solve给出符号解的时候,它是不会化简计算的。任何matlab的符号计算,包括四则运算、求导积分,都不具备化简/数值计算的功能。</p><p> 此外,solve函数还有一些选项可选,这使得符号求解名副其实,这才是solve的强大之处。运用solve函数,Name设定为'ReturnConditions',其值设定为true,表示要求solve函数输出详细信息。用这个方法我们可以得出一族解:</p><div></div><p> 而一般地,对于多变量的多项式(组),当多项式数量不足以确定所有参数时,按照以上设定,solve函数可以解出几个变量关于其他变量的函数:</p><div></div><p>assume</p><p> </p><p><strong>2. 多初值的数值解方程(组)函数 vpasolve</strong></p><p> 官方参考页:Solve equations numerically - MATLAB vpasolve</p><p>符号型数值标量/向量(即以数值的形式显示但实际上还是符号变量)。它的基本使用方式是:</p><div></div><p> 它的输入、功能和输出都和solve相仿。方程组的输入同样为行向量,变量组的输入也一样。</p><p> 当输入一个可以定解的多项式方程(组)时,vpasolve将会直接给出方程的数值解;若多项式方程数量不足以确定所有的解,那么vpasolve将会给出以剩余变量表示的所求变量的函数,只是表达式的一部分(系数等)可能会以数值的形式呈现。注意,有理分式方程将会多项式化以后一样处理。对于这些方程,init_guess的值写了也没用。</p><div></div><p> 对于多元方程组,vpasolve的输出也是struct结构体,访问方法也和solve输出的struct一样。不同的是,vpasolve无法求出含参的解,即无法设定'ReturnConditions'选项。和solve类似,除了多项式方程和有理分式方程以外的任何方程,vpasolve都不会给出全部解。这样一看,似乎vpasolve只不过就是把solve的结果全部转化为数值形式,甚至许多solve的功能都不能满足。这样的想法当然不对,vpasolve也有其自身的优势,这来源于:</p><p> A)可以设置初值进行数值求解。对于不可符号求解的方程,solve因为没有设定初值,可能无法搜索到合适的解。vpasolve则可以设置初值,从而可以进行后续解的搜索;B)可以随机取初值。我们都知道求解方程和最优化问题的初值选取非常玄学,而同样的初值最多只能有一个解。而结合循环等控制语句,利用vpasolve的随机初值功能可以让这一过程变得比较简单。比如可以写作初等函数的半整数阶Bessel(贝塞尔)函数,其零点有无穷多,但无法通过符号方法求解,在solve中会遇到很大的问题,但是用vpasolve设置合适的初值可以得到许多组临近初值的解。比如:</p><div></div><p> 另外,一些有限个解的方程,比如 $atanx=x/2$ ,我们已经知道它有解0,根据画图还可以确定在x>0和x<0范围内各有一个解。根据atanx的性质,我们知道所有的解肯定在区间[-5,5]之中。如果使用solve,每次均有警告并且输出一样,无法获得三个不同的解;即使是之后讲的fsolve也需要每次给定初始估计(init guess)。对于vpasolve,当确定范围了以后可以简单地使用循环的控制语句,只需要规定随机撒点的区间为[-5,5]:</p><div></div><p> 输出结果:</p><div></div><p> 很轻松地得到了该方程的全部解而不用再去手动猜测了。</p><p> </p><p><strong>3. 数值解方程(组)函数 fsolve</strong></p><p> 官方参考页:Solve system of nonlinear equations - MATLAB fsolve</p><p> fsolve可能是目前matlab的内置库函数中最常用的求(非线性)方程(组)解的函数,也是最为人熟知的。它用于数值求解方程(组),具有较广的适用范围(适用于高维和非线性、非多项式情形),甚至可以求矩阵方程的解(即甚至可以求解未知量为矩阵的情景)。fsolve函数的基本形式是:</p><div></div><p> 比如参考页面给出的示例非线性方程组:$$e^{-e^{x_1+x_2}}-x_2(1+x_1^2)=0$$ $$x_1cos(x_2)+x_2sin(x_1)=frac{1}{2}$$ 这是一个迷一般的方程组,嵌套的自然指数让人十分混乱,我们也并不期望得到这个方程的符号解或者解析解。我们将该方程组转化为matlab函数句柄:</p><div></div><p> 然后调用fsolve对于函数func进行求解,输出一个求解消息和解solution:</p><div></div><p> 需要注意的是,fsolve输入的函数句柄func<strong>只接受一个变量</strong>!fsolve可用于高维的情形,如例子中的二维,是通过将函数句柄的输入转化为向量实现的,即func接受一个向量形式的变量。对于创建一个输入参数为向量的函数句柄,简单地采用@方法似乎是行不通的。以上采用的方法是利用函数matlabFunction,定义变量('Var')为向量[x(1),x(2)],从而将符号变量f转化为函数句柄func。另一种可能更加普适(但更加麻烦)的方法参见官方参考页的示例或者matlab中函数fsolve的help文档,通过定义一个函数文件来实现这一操作(函数function文件和函数句柄是等价的)。</p><p> 函数fsolve提供了一些可以作为输出设置的options选项。options的设置如下:</p><div></div><p> 现在,尝试使用'iter'和'@optimplotfirstorderopt选项:</p><div></div><p> <br></p><p style="text-align:center;"><img src='https://s2.51cto.com/images/blog//0_6573dea43a24c72138.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184' alt='matlab的fsolve和Python的fsolve matlab fsolve()函数和solve_句柄' style="width: 483px; visibility: visible;"></p><p> 输出内容中,iteration为迭代次数,func-count为函数的总调用次数,f(x)为函数值的一个性质(暂时还没搞清楚是啥,毕竟二维映射不可能只有一个值),Norm of step应当是迭代步长(相邻迭代点间隔)的范数(模长),first order optimality 一阶优化条件,最终迭代是否终止的判据就是一阶优化条件是否足够接近零。绘图可以看出,随着迭代的进行,一阶优化条件趋于零。</p><p> 理论上,fsolve函数还允许指定求解的算法,比如使用单纯信赖域,或者使用狗腿信赖域,或者使用Levenberg-Marquardt算法。但总而言之,fsolve的算法均属优化算法,也因此在这里不足以讨论完全,留待优化部分的笔记说明。</p><p> </p><p><strong>4. 数值求一维函数零点函数 fzero</strong></p><p> 官方参考页:非线性函数的根 - MATLAB fzero</p><p> fzero用于求函数零点。这个函数<strong>致力于求解一维函数的零点</strong>。其基本形式:</p><div></div><p> fzero在应用上最令人高兴的是其丰富的输出内容,有利于观察迭代的结果,这用到options控制。options的控制方法为:</p><div></div><p> 然后将options变量带入函数即可。具体可以参见参考页,在此举两个例子,比如希望输出迭代的每一步:</p><div></div><p> 则有输出(节选):</p><div></div><p> 从中,我们可以看到每一步的x变化,f(x)的取值,甚至每一次迭代执行的操作:是二分法(bisection)或者插值类方法(interpolation)。我们还可以将迭代步骤可视化:</p><div></div><p> 输出图片:</p><p style="text-align:center;"><img src='https://s2.51cto.com/images/blog//0_6573dea.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184' alt='matlab的fsolve和Python的fsolve matlab fsolve()函数和solve_命令行_02' style="width: 505px; visibility: visible;"></p><p> </p><p><strong>5. 数值求多项式零点函数 roots</strong></p><p> 官方参考页:多项式根 - MATLAB roots</p><p> 除了求多项式根啥也干不了的一个函数,输入也和其他求根函数迥异。roots的标准形式如下,输入一个行向量,返回一个double型的列向量:</p><div></div><p> </p><p> roots也不是一无是处。相比于fzero和fsolve这样的函数,roots可以给出多项式的所有解,包括实数解和复数解:</p><div></div><p> </p><p> </p><p> <br></p><p> <br></p>
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/191740.html