To compute the gradient, my advice is to call makelist
and diff
as shown in my first answer. Let me take this opportunity to address some related topics.
I'll paste the definition of grad
shown in the problem statement and use that to make some comments.
grad(var,f) := block([aux],
aux : [gradient, DfDx[i]],
gradient : [],
DfDx[i] := diff(f(x_1,x_2,x_3),var[i],1),
for i in [1,2,3] do (
gradient : append(gradient, [DfDx[i]])
),
return(gradient)
)$
(1) Maxima works mostly with expressions as opposed to functions. That's not causing a problem here, I just want to make it clear. E.g. in general one has to say diff(f(x), x)
when f
is a function, instead of diff(f, x)
, likewise integrate(f(x), ...)
instead of integrate(f, ...)
.
(2) When gradient
and Dfdx
are to be the local variables, you have to name them in the list of variables for block
. E.g. block([gradient, Dfdx], ...)
-- Maxima won't understand block([aux], aux: ...)
.
(3) Note that a function defined with square brackets instead of parentheses, e.g. f[x] := ...
instead of f(x) := ...
, is a so-called array function in Maxima. An array function is a memoizing function, i.e. if f[x]
is called two or more times, the return value is only computed once, and then returned every time thereafter. Sometimes that's a useful optimization when the domain of the function comprises a finite set.
(4) Bear in mind that x_1
, x_2
, x_3
, are distinct symbols, not related to each other, and not related to x[1]
, x[2]
, x[3]
, even if they are displayed the same. My advice is to work with subscripted symbols x[i]
when i
is a variable.
(5) About building up return values, try to arrange to compute the whole thing at one go, instead of growing the result incrementally. In this case, makelist
is preferable to for
plus append
.
(6) The return
function in Maxima acts differently than in other programming languages; it's a little hard to explain. A function returns the value of the last expression which was evaluated, so if gradient
is that last expression, you can just write grad(var, f) := block(..., gradient)
.
Hope this helps, I know it's obscure and complex. The Maxima programming language was not designed before being implemented, and some of the decisions are clearly questionable at the long interval of more than 50 years (!) later. That's okay, they were figuring it out as they went along. There was not a body of established results which could provide a point of reference; the original authors were contributing to what's considered common knowledge today.