Example #1
0
 def _eval_evalf(self, prec):
     c, m = self.as_coeff_Mul()
     if c is S.NegativeOne:
         if m.is_Mul:
             rv = -AssocOp._eval_evalf(m, prec)
         else:
             mnew = m._eval_evalf(prec)
             if mnew is not None:
                 m = mnew
             rv = -m
     else:
         rv = AssocOp._eval_evalf(self, prec)
     if rv.is_number:
         return rv.expand()
     return rv
Example #2
0
    def __new__(cls, *args, **kwargs):
        evaluate = kwargs.get('evaluate', True)

        if not args:
            return VectorZero()

        args = list(map(sympify, args))
        # If for any reasons we create VecAdd(0), I want 0 to be returned.
        # Skipping this check, VectorZero() will be returned instead
        if len(args) == 1 and args[0] == S.Zero:
            return S.Zero

        if evaluate:
            # remove instances of S.Zero and VectorZero
            args = [
                a for a in args if not (isinstance(a, VectorZero) or
                                        (a == S.Zero) or (a == Vector.zero))
            ]
            if len(args) == 0:
                return VectorZero()
            elif len(args) == 1:
                # doesn't make any sense to have 1 argument in VecAdd if
                # evaluate=True
                return args[0]

        obj = AssocOp.__new__(cls, *args, evaluate=evaluate)
        obj = _sanitize_args(obj)

        # print("VecAdd OBJ", obj.func, obj)
        if not isinstance(obj, cls):
            return obj

        # are there any scalars or vectors?
        any_vectors = any([a.is_Vector for a in obj.args])
        all_vectors = all([a.is_Vector for a in obj.args])

        # addition of mixed scalars and vectors is not supported.
        # If there are scalars in the addition, either all arguments
        # are scalars (hence not a vector expression) or there are
        # mixed arguments, hence throw an error
        obj.is_Vector = all_vectors

        if (any_vectors and (not all_vectors)):
            asd = obj.args[1]
            print("####", asd.is_Vector, asd.args)
            print("####", [a.is_Vector for a in asd.args])
            for a in postorder_traversal(asd):
                print(a.func, a.is_Vector, a)
            raise TypeError("VecAdd: Mix of Vector and Scalar symbols:\n\t" +
                            "\n\t".join(
                                str(a.func) + ", " + str(a.is_Vector) + ", " +
                                str(a) for a in obj.args))
        return obj
Example #3
0
 def matches(self, expr, repl_dict={}):
     expr = sympify(expr)
     if self.is_commutative and expr.is_commutative:
         return AssocOp._matches_commutative(self, expr, repl_dict)
     elif self.is_commutative is not expr.is_commutative:
         return None
     c1, nc1 = self.args_cnc()
     c2, nc2 = expr.args_cnc()
     repl_dict = repl_dict.copy()
     if c1:
         if not c2:
             c2 = [1]
         a = Mul(*c1)
         if isinstance(a, AssocOp):
             repl_dict = a._matches_commutative(Mul(*c2), repl_dict)
         else:
             repl_dict = a.matches(Mul(*c2), repl_dict)
     if repl_dict:
         a = Mul(*nc1)
         if isinstance(a, Mul):
             repl_dict = a._matches(Mul(*nc2), repl_dict)
         else:
             repl_dict = a.matches(Mul(*nc2), repl_dict)
     return repl_dict or None
Example #4
0
 def matches(self, expr, repl_dict={}, old=False):
     return AssocOp._matches_commutative(self, expr, repl_dict, old)
Example #5
0
 def matches(self, expr, repl_dict={}, old=False):
     return AssocOp._matches_commutative(self, expr, repl_dict, old)
Example #6
0
    def __new__(cls, *args, **kwargs):
        evaluate = kwargs.get('evaluate', True)

        print("VecMul __new__", args)
        if not args:
            # it makes sense to return VectorOne, after all we are talking
            # about VecMul. However, this would play against us when using
            # expand(), because we would have multiplications of multiple
            # vectors (one of which, VectorOne).
            # Hence, better to return S.One.
            return S.One

        args = list(map(sympify, args))
        if len(args) == 1:
            # doesn't make any sense to have 1 argument in VecAdd if
            # evaluate=True
            return args[0]

        # # TODO: look through args (which are unprocessed as of now) for
        # # (a & nabla) * x (where x can be a scalar field or a vector field)
        # dot, field = None, None
        # skip_idx = []
        # dot_field = []
        # for i in range(len(args) - 1):
        #     if isinstance(args[i], VecDot) and isinstance(args[i].args[1], Nabla):
        #         dot = args[i]
        #         field = args[i + 1]
        #         skip_idx.extend([i, i + 1])

        vectors = [a.is_Vector for a in args]
        if vectors.count(True) > 1:
            raise TypeError(
                "Multiplication of vector quantities not supported\n\t" +
                "\n\t".join(str(a.func) + ", " + str(a) for a in args))

        # remove instances of S.One
        args = [a for a in args if a is not cls.identity]
        if len(args) == 0:
            return S.One
        if len(args) == 1:
            return args[0]

        if evaluate:
            # check if any vector is present
            args_is_vector = [a.is_Vector for a in args]
            if any([a == S.Zero for a in args]):
                if any(args_is_vector):
                    return VectorZero()
                return S.Zero
            if any([(isinstance(a, VectorZero) or (a == Vector.zero))
                    for a in args]):
                return VectorZero()
            if (all([not isinstance(a, VectorExpr) for a in args])
                    and any([not isinstance(a, Vector) for a in args])
                    and len(args) > 1):
                return reduce(mul, args)
                # return _prod(args)

        print("\t pre AssocOp.__new__", args)
        obj = AssocOp.__new__(cls, *args, evaluate=evaluate)
        obj = _sanitize_args(obj)
        print("\t post AssocOp.__new__", obj.func)
        for a in obj.args:
            print("\t\t", a.func, a.is_Vector, a)
        # obj = obj.func._exec_constructor_postprocessors(obj)

        # At this point, obj might not be of type VecMul. We must return
        # otherwise the next checks are going to be applied.
        # Example #1: VecMul(3, a + b) -> VecAdd(3 * a, 3 * b)
        # Example #2:
        # C = CoordSys3D("C")
        # vn1 = C.i + 2 * C.j + 3 * C.k
        # vn2 = x * C.i + y * C.j + z * C.k
        # VecMul(3, VecDot(vn1, vn2)).doit() -> Add(x, 2 * y, 3 * z)
        if not isinstance(obj, VecMul):
            return obj

        vectors = [a.is_Vector for a in obj.args]
        cvectors = vectors.count(True)
        obj.is_Vector = cvectors > 0

        if cvectors > 1:
            raise TypeError(
                "VecMul: Multiplication of vector quantities not supported\n\t"
                + "\n\t".join(
                    str(a.func) + ", " + str(a.is_Vector) + ", " + str(a)
                    for a in obj.args))
        return obj