# # Test 1:= keep_terms from cadabra import *; obj = Ex('a*(b+c)') distribute(obj,True) How do we do this on the C++ side? ----- With a preprocessor we could turn obj := A_{m n} B_{n p}; into obj = Ex('A_{m n} B_{n p}'); very easily and then all problems would go away. Ditto for distribute!(obj); to distribute(obj, all=True); algo options: all: like ! synonym for deep deep: like ! make deep=True the default actually, we could make this algo dependent; for some algorithms like vary it does not make sense to do a deep default. repeat: like !! make repeat=False the default We could also wrap distribute(%); since (% is not a valid python sequence of characters anyway. Properties: A_{m n}::Distributable(name='vector'); to Distributable('A_{m n}', name='vector'); sed -e 's/\(((\?!:=).)*\):=\(.*\)/\1 = Ex("\2")/' --------------------- Indices('m,n,p,q,r', name='vector'); ex = 'A_{m n} B_{m n}'; substitute(ex, 'B_{p q} -> C_{p} C_{q}'); obj1 = Ex('a1 + a2 + a3 + a4 + a5 + a6 + a7'); obj1 = Algo(obj1, True); obj1 = keep_terms(obj1, {2,4}); // auto-converts string to ex // it is pass by reference, so obj1 gets modified. None of // this silly obj1 = blabla(obj1) nonsense. tst1 = 'a3 + a4 + a5 - obj1'; // python objects are known on the cdb side. collect_terms(tst1); assert(tst1); ex = keep_terms('a1 + a2 + a3 + a4 + a5 + a6 + a7', {2,4}); @keep_terms(%){2}{4}; tst1:= a3 + a4 + a5 - @(obj1); @collect_terms!(%); @assert(tst1); ----- a:=A*(B+C); distribute(a, repeat=True); b:=A_{m n} (B^{n p} + C^{n p}); distribute(b); distribute('A_{m n} (B^{n p} + C^{n p})'); {a,b,c,d}::Indices; ex:=A_{c d} C^{d}; rename_dummies(ex); sort_product(ex) ex:=B ex:=A B A D C; rl:= B -> Q; substitute(ex, rl, True) {m,n,p,a,b}::Indices. ex:=A_{m n} ( C^{n p} + D^{n p} ); rl:= C^{a b} -> M_{m} D^{m a b}; substitute(ex, rl) from cadabra import * Indices(Ex('{m,n,p,a,b}')) ex=Ex('A_{m n} ( C^{n p} + D^{n p} )') rule=Ex('C^{a b} -> M_{m} D^{m a b}') substitute(ex, rule, True) substitute(ex, rl, True) ex:= B + A B A D C + A A D C; rl:= B -> 2; substitute(ex, rl) rl2:= A A D C -> 9 substitute(ex, rl2) ex:= B + A B A D C + A A D C; substitute(ex, rl) rl:= B -> 2; substitute(ex, rl2) {m,n,p,a,b}::Indices. ex:=A_{m n} ( C^{n p} + D^{n p} ); rl:= C^{a b} -> D^{a b}; substitute(ex, rl) ex1=Ex(0) ex2=Ex('0') ex3=Ex('1') print ex1==ex2 print ex2==ex3 print ex1==Ex(0) def test(): {m,n,p,a,b}::AntiCommuting. ex:=p m n a; sort_product(ex); print(ex); ex2:= A*(B+C); distribute(ex2); tst2:= A B + A C - @(ex2) print(tst2) collect_terms(tst2) if tst==Ex(0): print(tree(tst2)) print(tree(Ex(0)) test() # This does not see the property declared in test(): ex3:=p m n a; sort_product(ex3); print(ex3); a=3 ex:= A_{m n} @(a)