将符号导数转换为实际符号 [英] Transforming Symbolic Derivatives into Actual Symbols

查看:137
本文介绍了将符号导数转换为实际符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在Matlab中对很多方程进行导数运算.通用函数,它将为我提供以下类型的通用导数:

I need to take derivatives in Matlab of a lot of equations w.r.t. generic functions, which will provide me with generic derivatives, of the type:

diff(f(x,y),x)

D([1],f(x,y)).

我需要将这些导数转换为实际的符号变量,以便能够使用solve等.我现在正在做的,但是效率很低的是蛮力字符串替换.这是我正在做的最小工作示例:

What I need is to transform these derivatives into actual symbolic variables, in order to be able to use solve, etc. What I am doing now, but which is highly inefficient, is brute force string replacement. Here is a minimal working example of what I am doing:

syms x y
f(x,y) = sym('f(x,y)')
jacobian(f)
first_d = jacobian(f)
strrep(char(first_d),'D([1], f)(x, y)','fx')

在我的实际应用程序中,我需要从许多方程式中提取很多导数,因此循环进行此类替换并不是最明智的选择.任何人都可以为更有效的解决方案提供一些启发吗?

In my real application, I have lots of derivatives to take from lots of equations, so looping such replacements is not the smartest thing to do. Can anybody shed some light into a more efficient solution?

推荐答案

注意:我正在使用R2014b.在最近的版本中,符号数学功能已发生了很大的变化,并将继续如此.使用不同版本的用户可能需要做一些略有不同的事情才能获得下面的结果,这取决于访问未记录的功能.

首先,由于这与性能有关,因此只需声明就足够了

First, since this is about performance, it is sufficient to simply declare

syms f(x,y)

还将xy定义为符号变量.

which also defines x and y as symbolic variables.

正如我在上面的评论中提到的,Matlab/MuPAD的符号数学全部是关于操纵字符串的.更直接地执行此操作并添加您自己的问题知识可以帮助加快处理速度.您要避免在字符串和sym/symfun类型之间进行不必要的转换.

As I mention in my comments above, Matlab/MuPAD's symbolic math is all about manipulating strings. Doing this more directly and and adding in you own knowledge of the problem can help speed things up. You want to avoid unnecessary conversions between strings and the sym/symfun types.

1.首先要做的是研究特定的符号数学函数如何处理输入和输出以及它正在调用哪些较低级别的私有函数.对于您的 jacobian 函数示例,请在您的命令窗口以在编辑器中查看代码.您所看到的大部分内容可能会令人困惑,但是您应该看到以下行:

1. The first thing to do is investigate how a particular symbolic math function is handling input and output and what lower level private functions it is calling. In the case of your jacobian function example, type edit jacobian in your command window to view the code in the Editor. Much of what you see may be confusing, but you should see this line:

res = mupadmex('symobj::jacobian',Fsym.s,v.s);

这将调用低级'symobj::jacobian'函数,并传入该函数和变量的字符串版本.要自己调用它,您可以执行此操作(这还假设您知道变量为xy):

This calls the low level 'symobj::jacobian' function and passes in string versions of the function and variables. To call this yourself, you can do (this also assumes you know your variables are x and y):

syms f(x,y)
first_d = mupadmex('symobj::jacobian',char(f),char([x,y]))

这将返回[ diff(f(x, y), x), diff(f(x, y), y)].未记录的mupadmex函数是直接在Matlab中调用MuPAD函数的方法–

This returns [ diff(f(x, y), x), diff(f(x, y), y)]. The undocumented mupadmex function is a direct way of calling MuPAD function from within Matlab – there are others, which are documented.

2..您会注意到上面的first_d输出是symfun类.我们实际上不希望将输出转换回符号函数.为避免这种情况,我们可以向mupadmex传递一个加法参数:

2. You'll notice that that the first_d output above is symfun class. We actually don't want want the output to be converted back to a symbolic function. To avoid this, we can pass an addition argument to mupadmex:

syms f(x,y)
first_d = mupadmex('symobj::jacobian',char(f),char([x,y]),0)

with现在返回字符串matrix([[diff(f(x, y), x), diff(f(x, y), y)]]). (我只通过浏览大量的Symbolic Math工具箱代码而知道添加额外的0参数的技巧.)

with now returns the string matrix([[diff(f(x, y), x), diff(f(x, y), y)]]). (I only know this trick of adding the additional 0 argument from having browsed through a lot of Symbolic Math toolbox code.)

3..现在,您可以从该字符串中查找并替换具有简单变量的偏导数的各种模式.您使用的 strrep 函数通常是一个不错的选择为此的选择.它比 regexprep 快得多.但是,如果要替换大量不同但相似的模式,则可以在两者之间进行性能比较.那可能是一个单独问题的主题.

3. From this string, we can now find and replace various patterns for partial derivatives with simple variables. The strrep function that you're using is generally a good choice for this. It is much faster than regexprep. However, if you have a large number of different, but similar, patterns to replace, you might do a performance comparison between the two. That would probably be the subject of a separate question.

我不确定您的总体目标是什么或问题的全部范围,但是这是我为示例提供的最终代码:

I'm not sure what your overall goal is or the full extent of your problem, but here is my final code for your example:

syms f(x,y)
first_d = mupadmex('symobj::jacobian',char(f),char([x,y]),0)
first_d = strrep(first_d(9:end-2),'diff(f(x, y), x)','fx');
first_d = sym(strrep(first_d,'diff(f(x, y), y)','fy'));

这将返回符号向量[ fx, fy].如果需要symfun,则需要稍微修改最后一行.在一些简单的测试中,此基本示例比调用jacobian并将结果转换回字符串快约10%.如果直接将输入指定为字符串而不是分配符号函数,则结果将比原始结果快30%:

This returns the symbolic vector [ fx, fy]. If you want a symfun, you'll need to modify the last line slightly. In some simple testing, this basic example is about 10% faster than calling jacobian and converting the result back to a string. If you directly specify the inputs as strings instead of allocating a symbolic function, the result is about 30% faster then your original:

first_d = mupadmex('symobj::jacobian','f(x,y)','[x,y]',0)
first_d = strrep(first_d(9:end-2),'diff(f(x, y), x)','fx');
first_d = sym(strrep(first_d,'diff(f(x, y), y)','fy'));

使用 subs ,如

Using subs, as in this answer, while convenient, is the slowest approach. Converting back and forth to and from strings is costly.

这篇关于将符号导数转换为实际符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆