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.