0

I have following anonymous function (with x as an array):

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

I want to make gradient of this function and save it for future use. Also with array input.

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

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

Is it possible to archive this with this type of function? Or maybe it is possible to somehow make it via diff command? Something like this:

g = [diff(f, x(1));...
     diff(f, x(2));...
     diff(f, x(3));...
     diff(f, x(4))]
Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
AnJ
  • 581
  • 1
  • 6
  • 29

1 Answers1

1

I guess the following is what you want. I'm afraid, you need the Symbolic Math Toolbox for a simple solution, otherwise I'd rather calculate the derivatives by hand.

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)

or alternatively:

%// 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
Robert Seifert
  • 25,078
  • 11
  • 68
  • 113
  • Thanks, correctly calculated gradient. But i have a problem to run this on my code - http://pastebin.com/ahZR4Le3 (searching for function minimum with gradient method) `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);` – AnJ Nov 27 '16 at 11:17
  • maybe you should use the anonymous function `gd = matlabFunction(g)` instead of the symbolic one`? But I won't debug your code. Please ask a new concise question. The code above works, you just need to find out at which part you need to continue with yours. – Robert Seifert Nov 27 '16 at 11:26