sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.58k stars 4.33k forks source link

Are BaseDyadics commutative? #9375

Open mcho421 opened 9 years ago

mcho421 commented 9 years ago

On SymPy master (5cbd1c2c2facba833670e1fe26c314e72daa976e):

from sympy import Symbol
from sympy.vector import CoordSysCartesian
from sympy.vector.dyadic import BaseDyadic

N = CoordSysCartesian('N')
q = Symbol('q')
B = N.orient_new_axis('B', q, N.k)

b1 = BaseDyadic(B.i, N.i)
b2 = (B.i|N.i)
assert b1 == b2  # OK

print b1.is_commutative  # returns None
print b2.is_commutative  # returns True

I'm not an expert on this topic. I'm trying to solve this because its probably the last issue on https://github.com/sympy/sympy/pull/9374 before all the tests pass with SYMPY_USE_CACHE='no'.

This issue causes ./bin/doctest -C sympy/vector/functions.py to fail on https://github.com/sympy/sympy/pull/9374.

moorepants commented 9 years ago

A BaseDyadic, dyad, represents the multiplication (outer product) of two vectors. A dyadic is the sum of dyads. Dyadics can represent the basis independent form of a tensor.

jksuom commented 9 years ago

The outer product in the construction of b2 is built with the subclass DyadicMul of BasisDependentMul which is assumed commutative. This does not look right.

moorepants commented 9 years ago

@srjoglekar246 Can you comment here since you wrote the code?

srjoglekar246 commented 9 years ago

I think theres an issue with the construction of the BaseDyadics, thats creating problems after switching off the cache. I will look into this ASAP. b2 should not be an object of DyadicMul.

moorepants commented 9 years ago

@srjoglekar246, btw, Dyad may be a more correct term than BaseDyadic for this object. Or maybe UnitDyad. I think a dyad is the outer product of two vectors and a dyadic is a sum of dyads.

srjoglekar246 commented 9 years ago

Dyad seems a good option. Its essentially what I intended BaseDyadic to mean.

moorepants commented 9 years ago

If it is changed, I think it would have to be UnitDyad as a dyad is the outer product of any two vectors.

srjoglekar246 commented 9 years ago

I think the problem is with the way the b1 and b2 are being constructed. b1 goes through the constructor for BaseDyadic, whose ultimate ancestor is Expr - for whom, is_commutative returns None. For b2 however, the construction goes through the constructor for DyadicAdd, whose ultimate ancestor is Add - a commutative entity in SymPy. The best way to get around this (works in my system), is to define the is_commutative attribute in the code for BaseDyadic itself. @moorepants , would setting is_commutative = False for BaseDyadic, and True for the other subclasses of Dyadic, make sense?

moorepants commented 9 years ago

It isn't clear to me what is_commutative is. Does it mean commutative in addition, multiplication, dot product, etc? How can a mathematical object be universally commutative?

srjoglekar246 commented 9 years ago

I think (I am not 100% sure about this, @asmeurer can answer better) its with respect to the args of the class (Add or Mul or any other) in question. So if its an Add object with args (a, b), then the addtion is commutative with respect to a and b. So if we talk of the dyad b1 = (B.i|N.i), then BaseDyadic, as a mathematical operation, should not be commutative with respect to B.i and N.i.

moorepants commented 9 years ago

If we created DyadicMuls and DyadicAdds then I can imagine setting those objects to commutative or not. But I don't understand how we could set a BaseDyadic or a Dyadic to commutative or not.

jksuom commented 9 years ago

I agree. Commutativity is generally regarded as a property of an operation.

I don't understand why BaseVector is set commutative. Perhaps commutativity should not be set at all in sympy.vector. Commutativity is not touched in sympy.matrices even though the multiplication is non-commutative.

srjoglekar246 commented 9 years ago

Cant a BaseDyadic (name to be changed) be considered an operator acting on two vector operands? In such a case, is B.i | N.i != N.i | B.i, then we should set BaseDyadic as non-commutative? I agree about BaseVector though. It shouldn't have any notion of being either commutative or not. That was one of the few things I carried forward from Prasoon's code during my GSoC. I'll remove that line in my next PR. Weirdly, why does a SymPy Symbol also have is_commutative=True<./code>?

jksuom commented 9 years ago

When dyadics are represented by matrices B.i | N.i and N.i | B.i are transposes of each other. That they differ means that they not symmetric. (Perhaps we could call the outer product operation non-commutative but I don't think that would be useful as a property of the resulting dyad.)

srjoglekar246 commented 9 years ago

So the way would be to set BaseDyadic.is_commutative = None ? Lets have an opinion from someone who's worked with the assumptions system?

srjoglekar246 commented 9 years ago

@jcrist @moorepants I am opening a PR with some minor changes to the vector module (like renaming BaseDyadic), before sending the final commit to the docs PR. What do you guys think should be be the is_commutative attribute for Dyads and BaseVectors?

moorepants commented 9 years ago

@srjoglekar246 I'm not sure Dyad is correct. A Dyad is the outer product of any two vectors. A UnitDyad may be the outerproduct of two unit vectors. I think BaseDyadic may be the latter.

But I think this module may be in 0.7.6 already. It may not be worth changing this because you will have to deprecate it (although BaseDyadic is unlikely to have been used as a public class.).

It is a minor issue. The commutatitve stuff and the getting the docs merged are much more important.

Thanks for coming back to this.

nicoguaro commented 7 years ago

@moorepants, is this version of vector the same that the one under physics.vector?

moorepants commented 7 years ago

No, not exactly. The physics.vectors are immutable and designed to be a standard SymPy object. The ones in physics.mechanics.vector allow for the mutability so that derivatives can be assign post creation, which is needed in the mechanics module.

nicoguaro commented 7 years ago

@moorepants, I see ... I was considering starting with some tensor classes for stresses and strains for Continuum Mechanics. But I don't know how to proceed then. Any tips?

Also, there is probably a better place to discuss this. Should I open an Issue?

moorepants commented 7 years ago

An issue or the mailing list is fine. Note that we have tensors classes already that you may want to look into using. If you want to use these types of vectors and dyadics I suggest building off of sympy.vector. Only use sympy.physics.vector if you specifically need the immutability and the features that offers.