differentiating with respect to a variable in a list
Hi everyone, I have a small question. I'd like to make a function with a list as one argument and be able to take derivatives with respect to the variables encased in the list. The only such example among the built-in functions seems to be Li for lists in the second variable, but in this case all but the first element of that list seem to be ignored. Is there an example I've missed that I could look at, or some place that documents how this works? Thanks for your time. Karen
On Sat, May 21, 2005 at 01:15:18PM -0400, Karen Yeats wrote:
I'd like to make a function with a list as one argument and be able to take derivatives with respect to the variables encased in the list.
You don't want to do this, since such a function will break GiNaC's implementation of the chain rule. Probably, you need to define a function with variable number of arguments. Here is an example: /** * @file uniform_demo.cpp * Define a function, which is uniform w.r.t each argument. */ #include <iostream> #include <stdexcept> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; /** * (dummy) function for symbolic evaluation */ static ex uniform_eval(const exvector& ev) { return uniform(ev).hold(); } /** * differentiate uniform function * * @param ev - arguments, as a std::vector<GiNaC::ex> * @return the partial derivative w.r.t. diff_param-th argument */ static ex uniform_deriv(const exvector& ev, unsigned diff_param) { assert(diff_param < ev.size()); // d/dx_i f(x_1, ..., x_n) = x_i * f(x_1, ..., x_n) return ev[diff_param]*uniform(ev); } /** * Some cruft to make our function known to GiNaC. */ class uniform_SERIAL { public: static unsigned serial; }; /** * More cruft to make our function known to GiNaC. */ unsigned uniform_SERIAL::serial = function::register_new( function_options("uniform"). eval_func(uniform_eval). derivative_func(uniform_deriv)); /** * Just a convenient wrapper. */ inline function uniform(const exvector& ev) { return function(uniform_SERIAL::serial, ev); } /** * just demonstrate how it works */ int main(int argc, char** argv) { symbol x("x"); symbol y("y"); symbol z("z"); exvector ev; ev.push_back(x+y); ev.push_back(cos(x)+y); ev.push_back(z+x); ex test = uniform(ev); // f(x+y, cos(x)+y, z+x) ex tdiff = test.diff(x); cout << "d/dx (" << test << ") = " << tdiff << endl; return 0; } Hope this helps, Alexei.
participants (2)
-
Karen Yeats
-
varg@theor.jinr.ru