I have a solution and, as I thought earlier on, this is a side effect,
because the "state" called "evaluate" is a kind of global variable that can
cause side effects.
What I mean by side effect is when two functions, A and B, both use a
global variable x. When A changes x, it affects how B works, and that can
easily be undesired.
My mistake was in this code:
for kInd in range(0, 6):
with evaluate(False):
exp = exp + E(jInd, iInd, kInd)*(m-m0)**kInd
What I wanted was to calculate a partial sum (powers of m-m0) and I didn't
want these powers to be expanded. The problem is that evaluate(False) also
affects the inner working of E, so I changed it to this:
for kInd in range(0, 6):
exp1 = E(jInd, iInd, kInd)
with evaluate(False):
exp = exp + exp1*(m-m0)**kInd
That solves the problem.
Now, while we are on the subject of mistakes I made, here are some more. I
saw something that looked like a side effect, and I wanted to set the
"global variable" evaluate, but I didn't find that in the documentation, so
I tried a few things, like
exp = exp.subs(j, jIn, evaluate=True).subs(i, iIn,
evaluate=True).subs(m, m0, evaluate=True)
This is wrong, because evaluate is not an attribute, but a function.
exp = exp.subs(j, jIn, evaluate(True)).subs(i, iIn,
evaluate(True)).subs(m, m0, evaluate(True))
This is wrong, because subs does not expect a third parameter.
exp = exp.subs(j, jIn).evaluate(True).subs(i,
iIn).evaluate(True).subs(m, m0).evaluate(True)
This is wrong, because the Mul object does not have a method called
evaluate.
with evaluate(True):
exp = exp.subs(j, jIn).subs(i, iIn).subs(m, m0)
This is correct, and helped me find the solution, but it is unnecessary.
I also tried writing evaluate(False) in my test program, without the with,
but that didn't provoke the error.
In summary, what I needed to learn was that evaluate(False) will have an
effect on nested functions.
Thanks again to everyone who responded to my request.
On Monday, April 25, 2022 at 10:32:56 PM UTC+2 Thomas Ligon wrote:
> I'm still learning...
> if exp != 0:
> exp = exp.subs(j, jIn, evaluate=True).subs(i, iIn,
> evaluate=True).subs(m, m0, evaluate=True)
> and
> exp = simplify(exp, evaluate=True)
> didn't have any effect. This one
> exp = exp.doit()
> print('after doit', exp)
> ran for 90 minutes and I terminated it.
>
> On Monday, April 25, 2022 at 11:42:51 AM UTC+2 Thomas Ligon wrote:
>
>> Thanks! I thought I had copied too much traceback information, but we can
>> handle that later if necessary.
>> Your remark about unevaluated expressions looks like a very good place
>> for me to look, so I read the documentation and added a line of test code:
>> print('unevaluated part of exp', UnevaluatedExpr(exp))
>> Now the output looks like this:
>> after Eji -i*(i*j - 2*i*m + j**2 + 2*j*m + m**2)/(j*(2*j**2 + m**2))
>> after diff (-i*(i*j - 2*i*m + j**2 + 2*j*m + m**2)/(j*(2*j**2 +
>> m**2)))/factorial(0)
>> after subs (-1*(-2)*(m0**2 + 2*(-2)*m0 - 2*(-2)*m0 + (-2)**2 -
>> 2*(-2))/((-2)**1*(m0**2 + 2*(-2)**2)**1))/factorial(0)
>> unevaluated part of exp (-1*(-2)*(m0**2 + 2*(-2)*m0 - 2*(-2)*m0 + (-2)**2
>> - 2*(-2))/((-2)**1*(m0**2 + 2*(-2)**2)**1))/factorial(0)
>> How can I avoid this?`
>> One more remark: I use this when I return a value that should not be
>> expanded, for example:
>> with evaluate(False):
>> exp3 = (m-m0)**(Rational(2,3))*exp3
>> but the evaluate(False) should not be in effect here, and if it is, I
>> would need to turn if off.
>> On Friday, April 22, 2022 at 8:49:26 PM UTC+2 [email protected] wrote:
>>
>>> It's hard to say for sure without seeing the full traceback. The
>>> Mod(1*(2*0) + 1*(1*1), (1*1)*(1*2)) looks like it might be an
>>> unevaluated expression. If that's the case, those are known to cause
>>> issues because they can break the expectations of various functions.
>>>
>>> Aaron Meurer
>>>
>>> On Wed, Apr 20, 2022 at 2:23 AM Thomas Ligon <[email protected]>
>>> wrote:
>>> >
>>> > I am getting an exception where I don't see why it happens.
>>> >
>>> > The exception is:
>>> > invalid input: Mod(1*(2*0) + 1*(1*1), (1*1)*(1*2))
>>> >
>>> > The statement where it is being thrown is:
>>> > print(P3().subs(i, 0))
>>> > exp = factor(expand(P3().subs(i, 0)))
>>> >
>>> > P3() should always return the same thing:
>>> > def P3():
>>> > exp = 2*i**2 + 4*i*j + 8*i*m - j**2 +2*m*j + 9*m**2
>>> > return exp
>>> >
>>> > The print statement is just for debugging purposes. It shows me
>>> multiple times
>>> > -j**2 + 2*j*m + 9*m**2
>>> > then
>>> > 9*m**2 + j*(2*m) - j**2 + (8*0)*m + (4*0)*j + 2*0**2
>>> > invalid input: Mod(1*(2*0) + 1*(1*1), (1*1)*(1*2))
>>> >
>>> > So, I can't see why something that should work the same every time
>>> suddenly fails with an exception. The statement P3().subs(i, 0) should
>>> always return the same thing.
>>> >
>>> > A note on my coding style: P3 could easily be a global constant, but
>>> the function paradigm fits very well with the mathematics that I am
>>> reproducing. The most complex case I have runs recursively, which is very
>>> valuable. Also, I am using "exp" as a local variable that means
>>> "expression".
>>> >
>>> > --
>>> > You received this message because you are subscribed to the Google
>>> Groups "sympy" group.
>>> > To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> > To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/sympy/c427ce48-8d94-48df-a89c-fea3686b26a3n%40googlegroups.com.
>>>
>>>
>>>
>>
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/sympy/e250a7ad-8db4-4fee-b30b-045842f2b1c6n%40googlegroups.com.