Undefine the predefined numeric consant 'I'?
Is there an easy way to undefine the predefined numeric value 'I'? If I define a symbol 'I', use it in an expression, and then output that expression to cout after modifying stream with csrc, 'I' is converted to 'std::complex<double>(0.0,-1.0)'. I'd like the output to be just 'I'. Warren
On Fri, 1 Nov 2019 18:19:44 -0400, Warren Weckesser <warren.weckesser@gmail.com> said:
WW> Is there an easy way to undefine the predefined numeric value WW> 'I'? If I define a symbol 'I', use it in an expression, and WW> then output that expression to cout after modifying stream with WW> csrc, 'I' is converted to 'std::complex<double>(0.0,-1.0)'. I'd WW> like the output to be just 'I'. Would a string substitution be a solution to this? -- 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/ Jupyter (Colab): https://github.com/vvkisil/MoebInv-notebooks Jupyter (CodeOcean): https://codeocean.com/capsule/7952650/tree
On 11/2/19, Vladimir V. Kisil <kisilv@maths.leeds.ac.uk> wrote:
On Fri, 1 Nov 2019 18:19:44 -0400, Warren Weckesser <warren.weckesser@gmail.com> said:
WW> Is there an easy way to undefine the predefined numeric value WW> 'I'? If I define a symbol 'I', use it in an expression, and WW> then output that expression to cout after modifying stream with WW> csrc, 'I' is converted to 'std::complex<double>(0.0,-1.0)'. I'd WW> like the output to be just 'I'.
Would a string substitution be a solution to this?
Not really. The problem is not just the output. Ginac sets 'I' to be a predefined constant, so the code below prints e: -3-I*x de/dI: 0 instead of the desired e: 3*I^2 - x*I de/dI: 6*I - x For now, I'll just disallow the use of 'I' as a user-defined variable. Warren ----- #include <iostream> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; int main(int argc, char *argv[]) { symbol I("I"); symbol x("x"); symtab table; table["I"] = I; table["x"] = x; parser reader(table); ex e = reader("3*I*I - x*I"); cout << "e: " << e << endl; ex de = diff(e, I); cout << "de/dI: " << de << endl; return 0; } ----- I think for now, the simple rule is "Don't use I". I can add code to my program that disallows the use of 'I' on input. Warren
-- 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/ Jupyter (Colab): https://github.com/vvkisil/MoebInv-notebooks Jupyter (CodeOcean): https://codeocean.com/capsule/7952650/tree _______________________________________________ GiNaC-list mailing list GiNaC-list@ginac.de https://www.cebix.net/mailman/listinfo/ginac-list
Hi!
Would a string substitution be a solution to this?
Not really. The problem is not just the output. Ginac sets 'I' to be a predefined constant, so the code below prints
e: -3-I*x de/dI: 0
instead of the desired
e: 3*I^2 - x*I de/dI: 6*I - x
Actually the string substitution is enough. The trick is to replace "I" with something else in the *input*: #include <iostream> #include <ginac/ginac.h> using namespace GiNaC; int main(int argc, char **argv) { symbol I("I"), x("x"); symtab table{{"i", I}, {"x", x}}; parser reader{table}; ex e = reader("3*i*i - x*i"); ex eprime = e.diff(I); std::cout << "e = " << e << ", de/d" << I << " = " << eprime << std::endl; ex check = eprime - (6*I - x); if (!check.expand().is_zero()) { return 1; } return 0; } The output of the above program is: e = -I*x+3*I^2, de/dI = 6*I-x
For now, I'll just disallow the use of 'I' as a user-defined variable.
It's sort of similar to having a variable named `class` in a C++ code. I guess it's possible to hack the parser that way, however it's simpler to pick a different name (`theclass`, `class_`, etc) Hope this helps, Alexey
On 11/3/19, Alexey Sheplyakov <asheplyakov@yandex.ru> wrote:
Hi!
Would a string substitution be a solution to this?
Not really. The problem is not just the output. Ginac sets 'I' to be a predefined constant, so the code below prints
e: -3-I*x de/dI: 0
instead of the desired
e: 3*I^2 - x*I de/dI: 6*I - x
Actually the string substitution is enough. The trick is to replace "I" with something else in the *input*:
Thanks Alexey. A simple string substitution such as 'I' -> 'i' would not be safe. What if 'i' is also used in the expression? What if names such as 'I1', 'I2', 'Ion', etc., are also used? But maybe a regex-based substitution could work. (I'd rather not have to write a complete expression parser just for this--I'd rather let GiNaC to the work. :) Warren
#include <iostream> #include <ginac/ginac.h> using namespace GiNaC;
int main(int argc, char **argv) { symbol I("I"), x("x"); symtab table{{"i", I}, {"x", x}}; parser reader{table}; ex e = reader("3*i*i - x*i"); ex eprime = e.diff(I); std::cout << "e = " << e << ", de/d" << I << " = " << eprime << std::endl; ex check = eprime - (6*I - x); if (!check.expand().is_zero()) { return 1; } return 0; }
The output of the above program is:
e = -I*x+3*I^2, de/dI = 6*I-x
For now, I'll just disallow the use of 'I' as a user-defined variable.
It's sort of similar to having a variable named `class` in a C++ code. I guess it's possible to hack the parser that way, however it's simpler to pick a different name (`theclass`, `class_`, etc)
Hope this helps, Alexey _______________________________________________ GiNaC-list mailing list GiNaC-list@ginac.de https://www.cebix.net/mailman/listinfo/ginac-list
participants (3)
-
Alexey Sheplyakov
-
Vladimir V. Kisil
-
Warren Weckesser