Given a formal iterated derivative (GiNaC::fderivative), what actually is it?
Dear list, Using GiNaC one can define a symbolic/formal function f of two variables as follows: DECLARE_FUNCTION_2P(f) REGISTER_FUNCTION(f, dummy()) Formal derivatives can be computed by defining symbols x, y and calculating e.g. f(x,y).diff(x, 3).diff(y, 2) which is printed as D[0,0,0,1,1](f)(x,y) This is fantastic. Now, I would like to obtain the list [0, 0, 0, 1, 1] from the above expression. Checking the printing code GiNaC::fderivative::do_print, this is stored in a GiNaC::paramset. However, it's protected, and it doesn't seem to be accessible by any method. My attempt if (is_a<fderivative>(e)) { fderivative fder = ex_to<fderivative>(e); for (auto x : fder.parameter_set) cout << x << ", "; } therefore fails. Could an accessor or some such be implemented so this (basic) operation becomes possible? Best regards, Ricardo
Dear All,
On Thu, 7 Apr 2016 17:30:52 +0200, Ricardo Buring <ricardo.buring@gmail.com> said: RB> Now, I would like to obtain the list [0, 0, RB> 0, 1, 1] from the above expression. RB> Could an accessor or some such be implemented RB> so this (basic) operation becomes possible?
I am attaching a patch which returns the list of indices of the partial derivatives as op(nops()-1). Best wishes, Vladimir -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
Hi Vladimir, On 04/08/2016 02:08 PM, Vladimir V. Kisil wrote:
On Thu, 7 Apr 2016 17:30:52 +0200, Ricardo Buring <ricardo.buring@gmail.com> said: RB> Now, I would like to obtain the list [0, 0, RB> 0, 1, 1] from the above expression. RB> Could an accessor or some such be implemented RB> so this (basic) operation becomes possible?
I am attaching a patch which returns the list of indices of the partial derivatives as op(nops()-1).
Problem with that patch is that it breaks existing code which iterates over an fderivative object and doesn't expect the extra operand. I think we should find another way to expose the derivative structure. All my best, -richy. -- Richard B. Kreckel <http://in.terlu.de/~kreckel/>
On Mon, 11 Apr 2016 07:14:36 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said: RK> Problem with that patch is that it breaks existing code which RK> iterates over an fderivative object and doesn't expect the extra RK> operand. I think we should find another way to expose the RK> derivative structure.
OK, do you think if the patch will be re-written as a new method fderivative::get_der_indices() would be better? -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
Hi Vladimir, On 04/11/2016 12:52 PM, Vladimir V. Kisil wrote:
On Mon, 11 Apr 2016 07:14:36 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said: RK> Problem with that patch is that it breaks existing code which RK> iterates over an fderivative object and doesn't expect the extra RK> operand. I think we should find another way to expose the RK> derivative structure.
OK, do you think if the patch will be re-written as a new method fderivative::get_der_indices() would be better?
Yes, for the reason quoted above I think this should be a separate function. Considering that there is a public constructor with a paramset as argument, we can as well provide a const accessor member function to parameter_set and that's it. (True also, however, that said constructor could be protected.) Or maybe some completely different interface? What about this one: // how many times this function is derived with respect to parameter number param unsigned derived(unsigned param) const; That's why I was asking what the purpose is. All my best, -richy. -- Richard B. Kreckel <http://in.terlu.de/~kreckel/>
On Mon, 11 Apr 2016 22:03:23 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said: RK> Yes, for the reason quoted above I think this should be a RK> separate function.
RK> Considering that there is a public constructor with a paramset RK> as argument, we can as well provide a const accessor member RK> function to parameter_set and that's it. (True also, however, RK> that said constructor could be protected.) RK> Or maybe some completely different interface? What about this RK> one: // how many times this function is derived with respect to RK> parameter number param unsigned derived(unsigned param) const; I did not get the last reason. If GiNaC would provide a user with the full paramset, then (s)he will have a freedom to do anything with it. However, if GiNaC will pre-filter it out for one user's demand, then another user may not be able to (easily) get what (s)he want... -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
Dear Vladimir, On 04/12/2016 11:10 AM, Vladimir V. Kisil wrote:
On Mon, 11 Apr 2016 22:03:23 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said: RK> Yes, for the reason quoted above I think this should be a RK> separate function.
RK> Considering that there is a public constructor with a paramset RK> as argument, we can as well provide a const accessor member RK> function to parameter_set and that's it. (True also, however, RK> that said constructor could be protected.)
RK> Or maybe some completely different interface? What about this RK> one: // how many times this function is derived with respect to RK> parameter number param unsigned derived(unsigned param) const;
I did not get the last reason. If GiNaC would provide a user with the full paramset, then (s)he will have a freedom to do anything with it. However, if GiNaC will pre-filter it out for one user's demand, then another user may not be able to (easily) get what (s)he want...
Hmm, I don't feel fully comfortable with the abstraction in fderivative where the derivative structure is represented as a multiset<unsigned>. But you're probably right that, given the way this class is written, it is probably best to provide the full paramset. Patch suggestion attached. Will commit soon if no objection is raised. All my best, -richard. -- Richard B. Kreckel <http://in.terlu.de/~kreckel/>
Dear Richard, Partial derivatives are not very trivial mathematically either, probably their implementation in GiNaC reflects this. I think your patch provides a good rod, so any user can do his own fishing using it. Best wishes, Vladimir -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
On Thu, 14 Apr 2016 00:04:56 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said:
RK> Dear Vladimir, On 04/12/2016 11:10 AM, Vladimir V. Kisil wrote: >>>>>>> On Mon, 11 Apr 2016 22:03:23 +0200, "Richard B. Kreckel" >>>>>>> <kreckel@in.terlu.de> said: RK> Yes, for the reason quoted above I think this should be a RK> separate function. >> RK> Considering that there is a public constructor with a paramset RK> as argument, we can as well provide a const accessor member RK> function to parameter_set and that's it. (True also, however, RK> that said constructor could be protected.) >> RK> Or maybe some completely different interface? What about this RK> one: // how many times this function is derived with respect to RK> parameter number param unsigned derived(unsigned param) const; >> >> I did not get the last reason. If GiNaC would provide a user with >> the full paramset, then (s)he will have a freedom to do anything >> with it. However, if GiNaC will pre-filter it out for one user's >> demand, then another user may not be able to (easily) get what >> (s)he want... RK> Hmm, I don't feel fully comfortable with the abstraction in RK> fderivative where the derivative structure is represented as a RK> multiset<unsigned>. RK> But you're probably right that, given the way this class is RK> written, it is probably best to provide the full paramset. Patch RK> suggestion attached. Will commit soon if no objection is raised. RK> All my best, -richard. -- Richard B. Kreckel RK> <http://in.terlu.de/~kreckel/> RK> _______________________________________________ GiNaC-list RK> mailing list GiNaC-list@ginac.de RK> https://www.cebix.net/mailman/listinfo/ginac-list
Dear Richard, Vladimir, Thanks for discussing this. On Thu, Apr 14, 2016 at 12:04 AM, Richard B. Kreckel <kreckel@in.terlu.de> wrote:
Patch suggestion attached. Will commit soon if no objection is raised.
All my best, -richard.
This patch suggestion looks fine to me, save for some semantics: in English the verb is differentiate rather than derive, though in Dutch and some other languages the words are identical. The method could also be called derivatives() or derivative_indices(), or just indices(). Since the parameter_set is actually a multi-index, the method could also be called multi_index(). Whatever you decide to call it is fine with me. The reason I brought this up is that I'm constructing some complicated expressions involving (multiple) partial derivatives of a function f, and in the end I would like to obtain the coefficients in front of all the different derivatives of f. (This can easily be implemented after this patch is applied.) Best regards, Ricardo
Hi, On 04/07/2016 05:30 PM, Ricardo Buring wrote:
Using GiNaC one can define a symbolic/formal function f of two variables as follows:
DECLARE_FUNCTION_2P(f) REGISTER_FUNCTION(f, dummy())
Formal derivatives can be computed by defining symbols x, y and calculating e.g.
f(x,y).diff(x, 3).diff(y, 2)
which is printed as
D[0,0,0,1,1](f)(x,y)
This is fantastic.
Hmmm... Wouldn't it be more fantastic if it were printed D[x,x,x,y,y](f)(x,y)?
Now, I would like to obtain the list [0, 0, 0, 1, 1] from the above expression. Checking the printing code GiNaC::fderivative::do_print, this is stored in a GiNaC::paramset. However, it's protected, and it doesn't seem to be accessible by any method. My attempt
if (is_a<fderivative>(e)) { fderivative fder = ex_to<fderivative>(e); for (auto x : fder.parameter_set) cout << x << ", "; }
therefore fails. Could an accessor or some such be implemented so this (basic) operation becomes possible?
Sure. But what are you really trying to accomplish? (I'm asking because I want to find a rather general solution.) -richy. -- Richard B. Kreckel <http://in.terlu.de/~kreckel/>
On Sat, 9 Apr 2016 23:59:36 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said: >> f(x,y).diff(x, 3).diff(y, 2) >> which is printed as >> D[0,0,0,1,1](f)(x,y) >> This is fantastic.
RK> Hmmm... Wouldn't it be more fantastic if it were printed RK> D[x,x,x,y,y](f)(x,y)? But how to print f(x+y,x-y).diff(x, 3).diff(y, 2) in this case? -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
On 04/10/2016 12:23 AM, Vladimir V. Kisil wrote:
On Sat, 9 Apr 2016 23:59:36 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said: >> f(x,y).diff(x, 3).diff(y, 2) >> which is printed as >> D[0,0,0,1,1](f)(x,y) >> This is fantastic.
RK> Hmmm... Wouldn't it be more fantastic if it were printed RK> D[x,x,x,y,y](f)(x,y)?
But how to print f(x+y,x-y).diff(x, 3).diff(y, 2) in this case?
Well, I would have supposed like this: D[x+y,x+y,x+y,x+y,x+y](f)(x+y,x-y)+D[x+y,x+y,x+y,x+y,x-y](f)(x+y,x-y)-2*D[x+y,x+y,x+y,x-y,x-y](f)(x+y,x-y)-2*D[x+y,x+y,x-y,x-y,x-y](f)(x+y,x-y)+D[x+y,x-y,x-y,x-y,x-y](f)(x+y,x-y)+D[x-y,x-y,x-y,x-y,x-y](f)(x+y,x-y) A trivial patch is attached. All my best, -richy. -- Richard B. Kreckel <http://in.terlu.de/~kreckel/>
On Sun, 10 Apr 2016 11:33:59 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said:
RK> On 04/10/2016 12:23 AM, Vladimir V. Kisil wrote: >>>>>>> On Sat, 9 Apr 2016 23:59:36 +0200, "Richard B. Kreckel" >>>>>>> <kreckel@in.terlu.de> said: >> >> f(x,y).diff(x, 3).diff(y, 2) >> which is printed as >> >> D[0,0,0,1,1](f)(x,y) >> This is fantastic. >> RK> Hmmm... Wouldn't it be more fantastic if it were printed RK> D[x,x,x,y,y](f)(x,y)? >> >> But how to print f(x+y,x-y).diff(x, 3).diff(y, 2) in this case? RK> Well, I would have supposed like this: RK> D[x+y,x+y,x+y,x+y,x+y](f)(x+y,x-y)+D[x+y,x+y,x+y,x+y,x-y](f)(x+y,x-y)-2*D[x+y,x+y,x+y,x-y,x-y](f)(x+y,x-y)-2*D[x+y,x+y,x-y,x-y,x-y](f)(x+y,x-y)+D[x+y,x-y,x-y,x-y,x-y](f)(x+y,x-y)+D[x-y,x-y,x-y,x-y,x-y](f)(x+y,x-y) Yet, from a purist point of view, I have a concern that for f(x,x).diff(x, 3) the print-out will be ambiguous... -- Vladimir V. Kisil http://www.maths.leeds.ac.uk/~kisilv/ Book: Geometry of Mobius Transformations http://goo.gl/EaG2Vu Software: Geometry of cycles http://moebinv.sourceforge.net/
On 04/10/2016 12:39 PM, Vladimir V. Kisil wrote:
On Sun, 10 Apr 2016 11:33:59 +0200, "Richard B. Kreckel" <kreckel@in.terlu.de> said:
RK> On 04/10/2016 12:23 AM, Vladimir V. Kisil wrote: >>>>>>> On Sat, 9 Apr 2016 23:59:36 +0200, "Richard B. Kreckel" >>>>>>> <kreckel@in.terlu.de> said: >> >> f(x,y).diff(x, 3).diff(y, 2) >> which is printed as >> >> D[0,0,0,1,1](f)(x,y) >> This is fantastic. >> RK> Hmmm... Wouldn't it be more fantastic if it were printed RK> D[x,x,x,y,y](f)(x,y)? >> >> But how to print f(x+y,x-y).diff(x, 3).diff(y, 2) in this case?
RK> Well, I would have supposed like this: RK> D[x+y,x+y,x+y,x+y,x+y](f)(x+y,x-y)+D[x+y,x+y,x+y,x+y,x-y](f)(x+y,x-y)-2*D[x+y,x+y,x+y,x-y,x-y](f)(x+y,x-y)-2*D[x+y,x+y,x-y,x-y,x-y](f)(x+y,x-y)+D[x+y,x-y,x-y,x-y,x-y](f)(x+y,x-y)+D[x-y,x-y,x-y,x-y,x-y](f)(x+y,x-y)
Yet, from a purist point of view, I have a concern that for f(x,x).diff(x, 3) the print-out will be ambiguous...
That's correct. Thanks for pointing it out! -richy. -- Richard B. Kreckel <http://in.terlu.de/~kreckel/>
participants (3)
-
Ricardo Buring
-
Richard B. Kreckel
-
Vladimir V. Kisil