Symbols that are implicitly dependent on other symbols
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
participants (1)
-
Johan Rutgeerts