【问题标题】:Partial differentiation/gradient of anonymous function with array input具有数组输入的匿名函数的偏微分/梯度
【发布时间】:2016-11-26 19:29:19
【问题描述】:

我有以下匿名函数(x 作为数组):

f = @(x) 312*x(2) - 240*x(1) + 30*x(3) - 24*x(4) + 282*x(1)*x(2) + 30*x(1)*x(3) + 18*x(1)*x(4) + 54*x(2)*x(3) + 6*x(2)*x(4) + 6*x(3)*x(4) + 638*x(1)^2 + 207*x(2)^2 + 6*x(3)^2 + 3*x(4)^2 + 4063

我想制作这个函数的渐变并保存以备将来使用。还有数组输入。

X = [ 0;...
      0;...
      0;...
      0];

F = f(X)
G = g(X)

是否可以使用这种类型的功能进行存档?或者也许可以通过 diff 命令以某种方式实现它?像这样的:

g = [diff(f, x(1));...
     diff(f, x(2));...
     diff(f, x(3));...
     diff(f, x(4))]

【问题讨论】:

    标签: arrays matlab gradient differentiation


    【解决方案1】:

    我想以下是你想要的。恐怕您需要 Symbolic Math Toolbox 来获得简单的解决方案,否则我宁愿手动计算导数。

    x = [1 2 3 4];
    
    %// define function
    syms a b c d
    f = 312*b - 240*a + 30*c - 24*d + 282*a*b + 30*a*c + 18*a*d + 54*b*c + ...
        6*b*d +  6*c*d + 638*a^2 + 207*b^2 + 6*c^2 + 3*d^2 + 4063
    
    %// symbolic gradient
    g = gradient(f,[a,b,c,d])
    
    %// eval symbolic function
    F = subs(f,[a,b,c,d],x)
    G = subs(g,[a,b,c,d],x)
    
    %// convert symbolic value to double
    Fd = double(F)
    Gd = double(G)
    

    或者:

    %// convert symbolic function to anonymous function
    fd = matlabFunction(f)
    gd = matlabFunction(g)
    
    %// eval anonymous function
    x = num2cell(x)
    Fd = fd(x{:})
    Gd = gd(x{:})
    

    f =
    
    638*a^2 + 282*a*b + 30*a*c + 18*a*d - 240*a + 207*b^2 + 54*b*c + 
    6*b*d + 312*b + 6*c^2 + 6*c*d + 30*c + 3*d^2 - 24*d + 4063
    
    g =
    
     1276*a + 282*b + 30*c + 18*d - 240
       282*a + 414*b + 54*c + 6*d + 312
          30*a + 54*b + 12*c + 6*d + 30
            18*a + 6*b + 6*c + 6*d - 24
    
    F = 
    
     7179
    
    G =
    
     1762
     1608
      228
       48
    
    fd = 
    
        @(a,b,c,d)a.*-2.4e2+b.*3.12e2+c.*3.0e1-d.*2.4e1+a.*b.*2.82e2+a.*c.*3.0e1+a.*d.*1.8e1+b.*c.*5.4e1+b.*d.*6.0+c.*d.*6.0+a.^2.*6.38e2+b.^2.*2.07e2+c.^2.*6.0+d.^2.*3.0+4.063e3
    
    
    gd = 
    
        @(a,b,c,d)[a.*1.276e3+b.*2.82e2+c.*3.0e1+d.*1.8e1-2.4e2;a.*2.82e2+b.*4.14e2+c.*5.4e1+d.*6.0+3.12e2;a.*3.0e1+b.*5.4e1+c.*1.2e1+d.*6.0+3.0e1;a.*1.8e1+b.*6.0+c.*6.0+d.*6.0-2.4e1]
    
    
    x = 
    
        [1]    [2]    [3]    [4]
    
    
    Fd =
    
            7179
    
    
    Gd =
    
            1762
            1608
             228
              48
    

    【讨论】:

    • 谢谢,正确计算梯度。但我在我的代码上运行它时遇到问题 - pastebin.com/ahZR4Le3(使用梯度方法搜索函数最小值)Subscript indices must either be real positive integers or logicals. Error in sym/subsref (line 805) R_tilde = builtin('subsref',L_tilde,Idx); Error in gradient>@(a)f(D*a+X) Error in fminsearch (line 189) fv(:,1) = funfcn(x,varargin{:}); Error in gradient (line 45) [a,y] = fminsearch(fa,0);
    • 也许你应该使用匿名函数gd = matlabFunction(g)而不是符号函数`?但我不会调试你的代码。请提出一个新的简洁问题。上面的代码有效,你只需要找出你需要在哪一部分继续你的。
    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    相关资源
    最近更新 更多