Symbols that are implicitly dependent on other symbols

Johan Rutgeerts Johan.Rutgeerts at mech.kuleuven.ac.be
Fri Jan 16 10:34:53 CET 2004


Hi,

Is there some concept in Ginac of "symbols which are
function of some other symbol, but without making this explicit"?



I'll try to explain what I mean:


I wanted to:
- define some function f(q_1, q_2, ... q_m)
- calculate its derivatives df/d(q_j) symbolically and evaluate
  for specific values of q_j.

But just calculating the derivatives and substituting values for
q_j with subs(q_j == value) is far too slow for my application.



However, I can rewrite f: f(q_1, q_2,... ) == g(r_1, r_2,.., r_n),
in witch the r_i are functions of q_1, q_2,...,q_m.
And I have numeric methods to calculate the value of r_i and its
derivatives d(r_i)/d(q_j) for specific values of q_j.


So I would like to calculate df/d(q_j) as:

   df/d(q_j) == sum( dg/d(r_i) * d(r_i)/d(q_j), for all i),

using symbolic differentiation for the dg/d(r_i) and using the
numerically calculated values of the r_i and d(r_i)/d(q_j) in the 
evaluation (which should go a lot faster since g(r_i) is a fairly
simple function).



So for this I'd need to define g as a function of r_1 to r_n, but 
then the r_i must somehow know that they are function of q_1 to q_m,
otherwise the symbolic derivative dg/d(q_j) is zero.


So my question is: is there an easy way to do this in Ginac?





What I have an in mind as a possible solution is some kind of symbol
(let's call it "MySymbol" to be original:) that has awareness of its
numerical value and the value of its derivatives to certain variables.
This would then allow me to take the derivative and would eliminate
the use of subs(), making evaluation faster.


The class MySymbol would have methods like:

   void setValue(double value);
   void setDerivative(symbol var, unsigned int order, double value);
   

so that you can write:

  symbol q_j;
  MySymbol r_i;
  r_i.setValue(1.0);              // the numeric value of r_i is 1.0
  r_i.setDerivative(q_j, 1, 3.0); // the numeric value of d(r_i)/d(q_j) is 3.0
  r_i.setDerivative(q_j, 2, 2.0); // the numeric value of d^2(r_i)/d(q_j)^2 is 2.0
                                  // all other derivatives are standard zero

then e.g.:
 
  r_i.diff(q_j, 1) returns a "MySymbol" with "setValue(3.0)" and
                   "setDerivative(q_j, 1, 2.0)",
  r_i.diff(q_j, 2) returns a "numeric(2.0)",
  r_i.diff(q_j, i) with i > 2 returns a "numeric(0)",
  r_i.diff(l, 1)   returns a "numeric(0)" cause we never did a 
                   "setDerivative()" with l as parameter.
    


This should allow to write things like:

  MySymbol y = r_i + r_i.diff(q_j, 2) + r_i.diff(l, 1);
  double f = ex_to<double>( y ).to_double();

  cout << f << endl;  // should be "3.0"


and:

  cout << sin(r_i).diff(q_j,1) << endl;  // should be "cos(1.0)*3.0"

but also:

  cout << ( sin(r_i).diff(q_j,1) ).diff(q_j,1) << endl;

which should return the value of "cos(1.0) * 2.0 - sin(1.0) * (3.0)^2"



Does this seem feasible? Anyone see any big flaws, has
objections, knows a better name then "MySymbol"? ;)





A remark:
It might also be nice if one could do things like:

  symbol q_j;
  MySymbol r_i;
  r_i.setValue(1.0);            
  r_i.setDerivative(q, 1, 3.0); 

  MySymbol y = r_i + r_i.diff(q_j, 1);
  double f = ex_to<double>( y ).to_double();
    
  r_i.setValue(5.0);
  double g = ex_to<double>( y ).to_double(); // without reassigning y  

  cout << f << ", " << g << endl;  // prints "4.0, 8.0"


but this implies coupling between x and the object returned by e.g.
x.diff(...). Don't know if this is good.




Many greetings,

Johan Rutgeerts




More information about the GiNaC-list mailing list