我知道在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。考虑到某些函数可能不使用我声明的变量,例如x
和y
。
我知道内置fminunc
和fmincon
的MATLAB要求将函数变量定义为x(1)
,x(2)
,x(3)
....那个原因。
我想知道如何使用syms和subs来获取变量x(1)
,x(2)
,...,x(n)
的函数的渐变?
答案 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}的原因}}