Here's a short comment: using Idx(n+1) seems to work a little better for me, 
since I've noticed that if I use Idx(n) with a very complicated expression, 
there is a possibility of terms with (n+1) indices ending up on the same side 
as the (n) indices.
That sounds like a bug.  Can you give a specific example of an expression that 
does that?

Aaron Meurer


Sure, I can attempt to give an example. I've been unable to reproduce this behavior with a simple expression, so I am pasting below the full expression that I've been using. Of course, it may be something that I'm doing wrong, so I'm reluctant to cry wolf. But in a similar fashion to working with a building, if the pipes are a bit leaky, perhaps a small patch job would be beneficial if warranted.

The output of the example program below using Idx(n) shows that there are terms with p[i,j,n+1] on both sides of the equality. The equality == occurs three lines from the bottom of the output. See the first line of the output for a p[1, 1, 1 + n] term. Here is the output:

WRONG:

p[-1, 1, n]/deltax**4 + p[1, 1, 1 + n]*(3/deltax**4 + 0.5/(deltax**2*deltay**2) - A/(deltat**2*deltax**2) + A*p[1, 1, -1 + n]/(deltat**2*deltax**2*p[1, 1, n]) - A*p[0, 1, n]/(deltat**2*deltax**2*p[1, 1, n]) - A*p[2, 1, 1 + n]/(deltat**2*deltax**2*p[1, 1, n])) + p[2, 1, 1 + n]*(-4/deltax**4 - 1.0/(deltax**2*deltay**2) + 2*A/(deltat**2*deltax**2) - A*p[1, 1, -1 + n]/(deltat**2*deltax**2*p[1, 1, n])) - 4*p[0, 1, n]/deltax**4 + 3*p[1, 1, n]/deltax**4 + 0.5*p[1, 1, n]/(deltax**2*deltay**2) + 0.5*p[1, -1, n]/(deltax**2*deltay**2) + 0.5*p[-1, 1, n]/(deltax**2*deltay**2) + 0.5*p[-1, -1, n]/(deltax**2*deltay**2) + 2.0*p[0, 0, n]/(deltax**2*deltay**2) - 1.0*p[0, 1, n]/(deltax**2*deltay**2) - 1.0*p[0, -1, n]/(deltax**2*deltay**2) - 1.0*p[1, 0, n]/(deltax**2*deltay**2) - 1.0*p[-1, 0, n]/(deltax**2*deltay**2) - 2*A*p[1, 1, n]/(deltat**2*deltax**2) + A*p[1, 1, 1 + n]**2/(deltat**2*deltax**2*p[1, 1, n]) - A*p[1, 1, -1 + n]*p[0, 1, n]/(deltat**2*deltax**2*p[1, 1, n]) + 2*A*p[1, 1, n]*p[0, 1, n]/(deltat**2*deltax**2*p[1, 1, n]) == (-1/deltax**4 - 0.5/(deltax**2*deltay**2))*p[3, 1, 1 + n] + p[1, 2, 1 + n]/(deltax**2*deltay**2) + p[2, 3, 1 + n]/(deltax**2*deltay**2) + p[3, 2, 1 + n]/(deltax**2*deltay**2) - 0.5*p[1, 3, 1 + n]/(deltax**2*deltay**2) - 0.5*p[3, 3, 1 + n]/(deltax**2*deltay**2) - 2.0*p[2, 2, 1 + n]/(deltax**2*deltay**2) - A*p[1, 1, -1 + n]/(deltat**2*deltax**2)

If we use Idx(n+1) instead, the output appears to be right, and the p[i,j,n+1] are only on one side of the expression. This seems to be good:

RIGHT:

(deltax**(-4) + 0.5/(deltax**2*deltay**2))*p[3, 1, 1 + n] + p[1, 1, 1 + n]*(3/deltax**4 + 0.5/(deltax**2*deltay**2) - A/(deltat**2*deltax**2) + A*p[1, 1, -1 + n]/(deltat**2*deltax**2*p[1, 1, n]) - A*p[0, 1, n]/(deltat**2*deltax**2*p[1, 1, n]) - A*p[2, 1, 1 + n]/(deltat**2*deltax**2*p[1, 1, n])) + p[2, 1, 1 + n]*(-4/deltax**4 - 1.0/(deltax**2*deltay**2) + 2*A/(deltat**2*deltax**2) - A*p[1, 1, -1 + n]/(deltat**2*deltax**2*p[1, 1, n])) + 0.5*p[1, 3, 1 + n]/(deltax**2*deltay**2) + 0.5*p[3, 3, 1 + n]/(deltax**2*deltay**2) + 2.0*p[2, 2, 1 + n]/(deltax**2*deltay**2) - 1.0*p[1, 2, 1 + n]/(deltax**2*deltay**2) - 1.0*p[2, 3, 1 + n]/(deltax**2*deltay**2) - 1.0*p[3, 2, 1 + n]/(deltax**2*deltay**2) + A*p[1, 1, 1 + n]**2/(deltat**2*deltax**2*p[1, 1, n]) == -p[-1, 1, n]/deltax**4 - 3*p[1, 1, n]/deltax**4 + 4*p[0, 1, n]/deltax**4 + p[0, 1, n]/(deltax**2*deltay**2) + p[0, -1, n]/(deltax**2*deltay**2) + p[1, 0, n]/(deltax**2*deltay**2) + p[-1, 0, n]/(deltax**2*deltay**2) - 0.5*p[1, 1, n]/(deltax**2*deltay**2) - 0.5*p[1, -1, n]/(deltax**2*deltay**2) - 0.5*p[-1, 1, n]/(deltax**2*deltay**2) - 0.5*p[-1, -1, n]/(deltax**2*deltay**2) - 2.0*p[0, 0, n]/(deltax**2*deltay**2) - A*p[1, 1, -1 + n]/(deltat**2*deltax**2) + 2*A*p[1, 1, n]/(deltat**2*deltax**2) + A*p[1, 1, -1 + n]*p[0, 1, n]/(deltat**2*deltax**2*p[1, 1, n]) - 2*A*p[1, 1, n]*p[0, 1, n]/(deltat**2*deltax**2*p[1, 1, n])


Nicholas


#begin sample code
from sympy import *
from sympy.tensor import Indexed, Idx, IndexedBase
from sympy.matrices import *

p = IndexedBase('p')
var('deltax deltay delta deltat A B')
i,j,n = symbols('i j n', integer = True)

#
# function to generate the FDTD scheme
#
# All p[i,j,n+1] indices should be collected and on the LHS of the expression
def generate_fdtd(expr, nsolve):
    expr0 = expr.lhs - expr.rhs
    expr1 = expr0.expand()
    w1 = Wild('w1',integer=True)
    w2 = Wild('w2',integer=True)
    expr2 = collect(expr1, p[w1, w2, nsolve])
expr3 = expr2.as_independent(*filter(lambda t: t.args[-1] == Idx(n), expr2.atoms(Indexed) ) )
    #Uncomment line for proper behavior
#expr3 = expr2.as_independent(*filter(lambda t: t.args[-1] == Idx(n+1), expr2.atoms(Indexed) ) )
    left = expr3[0]
    right = expr3[1]
    left = -1 * expr3[0]
    left = left.expand()
    left = collect(left, p[w1,w2,nsolve])
    right = expr3[1]
    return Eq(right, left)



def main():
expr = Eq( 0.5*((-2*p[1, 2, 1 + n] - 2*p[2, 1, 1 + n] - 2*p[2, 3, 1 + n] - 2*p[3, 2, 1 + n] + 4*p[2, 2, 1 + n] + p[1, 1, 1 + n] + p[1, 3, 1 + n] + p[3, 1, 1 + n] + p[3, 3, 1 + n])/(deltax**2*deltay**2) + (-2*p[0, 1, n] - 2*p[0, -1, n] - 2*p[1, 0, n] - 2*p[-1, 0, n] + 4*p[0, 0, n] + p[1, 1, n] + p[1, -1, n] + p[-1, 1, n] + p[-1, -1, n])/(deltax**2*deltay**2)) + (-4*p[0, 1, n] - 4*p[2, 1, 1 + n] + 3*p[1, 1, n] + 3*p[1, 1, 1 + n] + p[-1, 1, n] + p[3, 1, 1 + n])/deltax**4, A*(-2*p[1, 1, n] + p[1, 1, 1 + n] + p[1, 1, -1 + n])*(-p[1, 1, n] - p[1, 1, 1 + n] + p[0, 1, n]
                + p[2, 1, 1 + n])/(deltat**2*deltax**2*p[1, 1, n]) )

    print generate_fdtd(expr,n+1)


if __name__ == "__main__":
    main()
# end sample code

--
You received this message because you are subscribed to the Google Groups 
"sympy" group.
To post to this group, send email to sy...@googlegroups.com.
To unsubscribe from this group, send email to 
sympy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sympy?hl=en.

Reply via email to