Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

from __future__ import print_function, division 

 

from sympy.core import Mul, sympify 

from sympy.strategies import unpack, flatten, condition, exhaust, do_one 

 

from sympy.matrices.expressions.matexpr import MatrixExpr, ShapeError 

 

def hadamard_product(*matrices): 

    """ 

    Return the elementwise (aka Hadamard) product of matrices. 

 

    Examples 

    ======== 

 

    >>> from sympy.matrices import hadamard_product, MatrixSymbol 

    >>> A = MatrixSymbol('A', 2, 3) 

    >>> B = MatrixSymbol('B', 2, 3) 

    >>> hadamard_product(A) 

    A 

    >>> hadamard_product(A, B) 

    A.*B 

    >>> hadamard_product(A, B)[0, 1] 

    A[0, 1]*B[0, 1] 

    """ 

    if not matrices: 

        raise TypeError("Empty Hadamard product is undefined") 

    validate(*matrices) 

    if len(matrices) == 1: 

        return matrices[0] 

    else: 

        return HadamardProduct(*matrices).doit() 

 

 

class HadamardProduct(MatrixExpr): 

    """ 

    Elementwise product of matrix expressions 

 

    This is a symbolic object that simply stores its argument without 

    evaluating it. To actually compute the product, use the function 

    ``hadamard_product()``. 

 

    >>> from sympy.matrices import hadamard_product, HadamardProduct, MatrixSymbol 

    >>> A = MatrixSymbol('A', 5, 5) 

    >>> B = MatrixSymbol('B', 5, 5) 

    >>> isinstance(hadamard_product(A, B), HadamardProduct) 

    True 

    """ 

    is_HadamardProduct = True 

 

    def __new__(cls, *args, **kwargs): 

        args = list(map(sympify, args)) 

        check = kwargs.get('check'   , True) 

        if check: 

            validate(*args) 

        return super(HadamardProduct, cls).__new__(cls, *args) 

 

    @property 

    def shape(self): 

        return self.args[0].shape 

 

    def _entry(self, i, j): 

        return Mul(*[arg._entry(i, j) for arg in self.args]) 

 

    def _eval_transpose(self): 

        from sympy.matrices.expressions.transpose import transpose 

        return HadamardProduct(*list(map(transpose, self.args))) 

 

    def doit(self, **ignored): 

        return canonicalize(self) 

 

def validate(*args): 

    if not all(arg.is_Matrix for arg in args): 

        raise TypeError("Mix of Matrix and Scalar symbols") 

    A = args[0] 

    for B in args[1:]: 

        if A.shape != B.shape: 

            raise ShapeError("Matrices %s and %s are not aligned" % (A, B)) 

 

rules = (unpack, 

         flatten) 

 

canonicalize = exhaust(condition(lambda x: isinstance(x, HadamardProduct), 

                                 do_one(*rules)))