Changing symbol string names on-the-fly
Is it possible to change on-the-fly the string names used in a symbol? For example, I am considering programs with several thousands of variables and wish to output the code for the expressions in csrc-format. The names used internally utilize the object-partitioning of my code e.g. : symbol x("system[1].composition.x[2]") The output in raw C++ form is desired to be a simple counting scheme e.g. for the above symbol: "var[101]" will be substituted. I have tried to use an auxiliary vector list with new symbols and then substitute the new symbols for the old, using .subs(). However, when the number of substitutions is beyond say a couple of hundred even a 2.5 GHz machine cannot run the problem efficiently. I proceeded to test further abstract examples of substitutions and found that the .subs() method can indeed be extremely slow (inefficient?) in general. Without resorting to brute force outputing and replacing of strings, I wonder if there is an elegant and economical way to do the above in GiNaC. Vassilis. ----------------------------------------------------------------- Dr. Vassilis S. Vassiliadis, Lecturer, UNIVERSITY OF CAMBRIDGE, DEPARTMENT OF CHEMICAL ENGINEERING Pembroke Street, Cambridge CB2 3RA, UK. Tel: (reception): +44 1223 334777 Fax: (departmental): +44 1223 334796 WWW: www.cheng.cam.ac.uk/~vsv20 e-mail: vsv20@cheng.cam.ac.uk -----------------------------------------------------------------
Hi! On Wed, Jul 09, 2003 at 11:02:07AM +0100, Dr. Vassilis S. Vassiliadis wrote:
Is it possible to change on-the-fly the string names used in a symbol?
There is a symbol::set_name(), but it only works for symbols that are not already part of an expression.
The names used internally utilize the object-partitioning of my code e.g. : symbol x("system[1].composition.x[2]")
The output in raw C++ form is desired to be a simple counting scheme e.g. for the above symbol: "var[101]" will be substituted.
Maybe we should add a "csrc" name for symbols in the same manner as there is a TeX name. But this seems like overkill...
I have tried to use an auxiliary vector list with new symbols and then substitute the new symbols for the old, using .subs().
subs() would be the recommended solution to your problem.
However, when the number of substitutions is beyond say a couple of hundred even a 2.5 GHz machine cannot run the problem efficiently.
Specifying subs_options::subs_no_pattern might speed it up. If it's still too slow, find out why and send us a patch. :-) Maybe subs() should use maps instead of lists?
Without resorting to brute force outputing and replacing of strings, I wonder if there is an elegant and economical way to do the above in GiNaC.
There is another way that is undocumented but gets the job done: symbols can be assigned expressions, including other symbols: symbol a("a"), b("b"); ex e = a + 2*b; cout << e << endl; // prints "2*b+a" a.assign(symbol("foo")); b.assign(symbol("bar")); cout << e.eval() << endl; // prints "2*bar+foo", the eval() is necessary Bye, Christian -- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/
Dear Christian, thanks for the tips. I shall try your suggestions today. One issue: I think yes, the .subs() method should use maps or some hash structure to speed things up. Vassilis ----- Original Message ----- From: "Christian Bauer" <Christian.Bauer@Uni-Mainz.DE> To: <ginac-list@thep.physik.uni-mainz.de> Sent: Wednesday, July 09, 2003 6:40 PM Subject: Re: Changing symbol string names on-the-fly
Hi!
On Wed, Jul 09, 2003 at 11:02:07AM +0100, Dr. Vassilis S. Vassiliadis wrote:
Is it possible to change on-the-fly the string names used in a symbol?
There is a symbol::set_name(), but it only works for symbols that are not already part of an expression.
The names used internally utilize the object-partitioning of my code e.g. : symbol x("system[1].composition.x[2]")
The output in raw C++ form is desired to be a simple counting scheme e.g. for the above symbol: "var[101]" will be substituted.
Maybe we should add a "csrc" name for symbols in the same manner as there is a TeX name. But this seems like overkill...
I have tried to use an auxiliary vector list with new symbols and then substitute the new symbols for the old, using .subs().
subs() would be the recommended solution to your problem.
However, when the number of substitutions is beyond say a couple of hundred even a 2.5 GHz machine cannot run the problem efficiently.
Specifying subs_options::subs_no_pattern might speed it up. If it's still too slow, find out why and send us a patch. :-)
Maybe subs() should use maps instead of lists?
Without resorting to brute force outputing and replacing of strings, I wonder if there is an elegant and economical way to do the above in GiNaC.
There is another way that is undocumented but gets the job done: symbols can be assigned expressions, including other symbols:
symbol a("a"), b("b"); ex e = a + 2*b; cout << e << endl; // prints "2*b+a" a.assign(symbol("foo")); b.assign(symbol("bar")); cout << e.eval() << endl; // prints "2*bar+foo", the eval() is necessary
Bye, Christian
-- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/
Hi! On Thu, Jul 10, 2003 at 10:05:46AM +0100, Dr. Vassilis S. Vassiliadis wrote:
thanks for the tips. I shall try your suggestions today.
Addendum: You can actually use symbol::set_name(), but then you have to know exactly what your objects are. For example, the naive approach doesn't work: symbol a("a"), b("b"); ex e = a + 2*b; a.set_name("foo"); b.set_name("bar"); cout << e << endl; // prints "2*b+a" because the symbol objects in the expression are heap-allocated copies of "a" and "b", but this works: symbol &a_sym = *new symbol("a"); a_sym.setflag(status_flags::dynallocated); symbol &b_sym = *new symbol("b"); b_sym.setflag(status_flags::dynallocated); ex a = a_sym, b = b_sym; ex e = a + 2*b; a_sym.set_name("foo"); b_sym.set_name("bar"); cout << e << endl; // prints "2*bar+foo"
One issue: I think yes, the .subs() method should use maps or some hash structure to speed things up.
I'll have a look at it. Bye, Christian -- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/
On the previous discussion, of changing names & substitutions: The highest speed with the previous hints provided (below) the best and most impressive is obtained with the .assign(...) method. I have found it extremely efficient both in terms of replacing symbols with other symbols, as well as for evaluation of a large function upon numerical assignments through a temporary auxiliary expression carrying a numerical value. Vassilis. ----------------------------------------------------------------- Dr. Vassilis S. Vassiliadis, Lecturer, UNIVERSITY OF CAMBRIDGE, DEPARTMENT OF CHEMICAL ENGINEERING Pembroke Street, Cambridge CB2 3RA, UK. Tel: (reception): +44 1223 334777 Fax: (departmental): +44 1223 334796 WWW: www.cheng.cam.ac.uk/~vsv20 e-mail: vsv20@cheng.cam.ac.uk ----------------------------------------------------------------- ----- Original Message ----- From: "Christian Bauer" <Christian.Bauer@Uni-Mainz.DE> To: <ginac-list@thep.physik.uni-mainz.de> Sent: Wednesday, July 09, 2003 6:40 PM Subject: Re: Changing symbol string names on-the-fly
Hi!
On Wed, Jul 09, 2003 at 11:02:07AM +0100, Dr. Vassilis S. Vassiliadis wrote:
Is it possible to change on-the-fly the string names used in a symbol?
There is a symbol::set_name(), but it only works for symbols that are not already part of an expression.
The names used internally utilize the object-partitioning of my code e.g. : symbol x("system[1].composition.x[2]")
The output in raw C++ form is desired to be a simple counting scheme e.g. for the above symbol: "var[101]" will be substituted.
Maybe we should add a "csrc" name for symbols in the same manner as there is a TeX name. But this seems like overkill...
I have tried to use an auxiliary vector list with new symbols and then substitute the new symbols for the old, using .subs().
subs() would be the recommended solution to your problem.
However, when the number of substitutions is beyond say a couple of hundred even a 2.5 GHz machine cannot run the problem efficiently.
Specifying subs_options::subs_no_pattern might speed it up. If it's still too slow, find out why and send us a patch. :-)
Maybe subs() should use maps instead of lists?
Without resorting to brute force outputing and replacing of strings, I wonder if there is an elegant and economical way to do the above in GiNaC.
There is another way that is undocumented but gets the job done: symbols can be assigned expressions, including other symbols:
symbol a("a"), b("b"); ex e = a + 2*b; cout << e << endl; // prints "2*b+a" a.assign(symbol("foo")); b.assign(symbol("bar")); cout << e.eval() << endl; // prints "2*bar+foo", the eval() is necessary
Bye, Christian
-- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/
participants (3)
-
Christian Bauer
-
Dr. Vassilis S. Vassiliadis
-
Jens Vollinga