MATLAB符号替换

时间:2015-09-26 14:23:05

标签: matlab gradient

我知道在MATLAB中是否声明

syms x y
f=x^2+y^2
grad=gradient(f)

然后,grad将存储值[2*x;2*y]

如果我想在[2;2]评估渐变,我会使用

subs(f,[x;y],[2,2])

这会返回[4;4]

我正在编写一个最速的下降算法,该算法需要足够通用才能承担任何功能。我想知道如何一般地使用syms和subs。考虑到某些函数可能不使用我声明的变量,例如xy

我知道内置fminuncfmincon的MATLAB要求将函数变量定义为x(1)x(2)x(3) ....那个原因。

我想知道如何使用syms和subs来获取变量x(1)x(2),...,x(n)的函数的渐变?

1 个答案:

答案 0 :(得分:3)

查看函数symvar。这将解析一个字符串并从中提取变量名称(但它不会将v(i)解释为向量的元素;它将假定它是一个函数)。这与用于解析自定义曲线拟合模型中的变量的函数相同。

funstr = 'x^2+y^2';
varcell = symvar(funstr)
如果我没有弄错的话,

将按字典顺序返回函数的自变量作为单元格数组。幸运的是,您可以使用此单元格数组来计算渐变并随后替换:

grad = gradient(sym(funstr),varcell);
varvec = rand(1,length(varcell));
gradval = subs(grad,varcell,varvec);

虽然gradient会给你一个没有单元格数组输入的渐变(无论如何都可能使用symvar)。通过将单元格数组varcell提供给subs,您可以严格控制变量的顺序(这可能对替换很重要)。

为了使用户提供的变量顺序与symvar返回的顺序相匹配,您仍需要弄清楚其背后的后勤,但似乎可行。您最好的机会可能是计算一次渐变,然后使用matlabFunction构建一个匿名函数,用于实际(数值)下降:

matlabFunction(grad)

ans = 

    @(x,y)[x.*2.0;y.*2.0]

如果问题是输入数量可变,您可以强制matlabFunction接受矢量输入:

matlabFunction(grad,'vars',{sym(varcell)})

ans = 

    @(in1)[in1(1,:).*2.0;in1(2,:).*2.0]

由于原因,matlabFunction仅假设向量输入,如果其单元格参数具有符号向量元素,这就是我们需要{sym(varcell)}{'x', 'y'}转换为{{1}的原因}}