mmj
mmj

Reputation: 5780

Sympy: prevent a subscripted symbol to be evaluated

Given a symbol s, which ultimately will be an Array, I want to define the following expression

A = Array([-s[1]/2, s[0]/2])

but I'd like A to be evaluated only when I compute some other expressions containing it, because s changes over time. I tried

A = UnevaluatedExpr(Array([-s[1]/2,s[0]/2]))

but I got the error TypeError: 'Symbol' object is not subscriptable, which make me think that some evaluation is performed on s.

Thanks for your patience, I'm just learning Sympy and I'm used to Maxima where this kind of construct is straightforward. To be more precise, with Maxima the full working code I'm trying to translate into Sympy is (in Maxima everything is a symbol, colon is the assignment operator, ev forces evaluation with custom values, the dot before diff is the vector scalar product):

A: [-s[2],s[1]]/2; /* define A in terms of subscripted symbols */
P1: [x1,y1];
P2: [x2,y2];
segment: P1+t*(P2-P1); /* --> [t*(x2-x1)+x1,t*(y2-y1)+y1] */
factor(integrate(ev(A,s=segment).diff(segment,t),t,0,1)); /* integrates the scalar product of A evaluated over segment and the derivative of segment */

Follow up

Thanks to Oscar answer I was able to come up with a working Sympy translation of the above Maxima code (improvements are welcomed!):

from sympy import *

def dotprod(*vectors): # scalar product, is there a built in better way?
    return sum(Mul(*x) for x in zip(*vectors))

s = IndexedBase('s')
A = Array([-s[1]/2,s[0]/2])

t,x1,y1,x2,y2 = symbols('t x1 y1 x2 y2')
P1 = Array([x1,y1])
P2 = Array([x2,y2])
segment = P1 + t * (P2-P1)

dotprod(A.subs(s,segment),segment.diff(t)).integrate((t,0,1)).factor()

Apart from the IndexedBase magic the structure of the code in Maxima and Sympy is very similar.

Upvotes: 1

Views: 192

Answers (1)

Oscar Benjamin
Oscar Benjamin

Reputation: 14480

I'm not sure I understand what you want. It's possible that your problem is better approached in a different way rather than using Array. In any case a direct answer to your question is that you can use IndexedBase to make a subscriptable symbol:

In [1]: s = IndexedBase('s')

In [2]: A = Array([-s[1]/2, s[0]/2])

In [3]: A
Out[3]: 
⎡-s[1]   s[0]⎤
⎢──────  ────⎥
⎣  2      2  ⎦

Upvotes: 1

Related Questions