

下記の積関数を拡張し，行列×ベクトルと行列×行列の掛け算を行うコードを書きたいのですが，うまくできません....  
行列×ベクトルはうまく実行できているのですが....  
またその際，掛ける側がベクトルか行列かで計算を変える必要があります。  
分かるかたお教えいただければ幸いです。

[code]

    from operator import mul
    
    class Vector:
        def __init__(self,*args):
            self.num = args
    
        def out(self):
            print(self.num)
    
    class Matrix:
      def __init__(self, *args):
        self.matrix = args
    
      def __mul__(self, tensor):
        if isinstance(tensor, Vector):
          print(Vector(*[sum([col*tensor.num[i] for i, col in enumerate(row)]) for row in self.matrix]))
          return Vector(*[sum([col*tensor.num[i] for i, col in enumerate(row)]) for row in self.matrix])
        elif isinstance(tensor, Matrix):
          print([[sum(map(mul, row, col)) for col in zip(*self.matrix)] for row in tensor.matrix])
          return [[sum(map(mul, row, col)) for col in zip(*self.matrix)] for row in tensor.matrix]
        else:
          raise TypeError('Not a Vector or Matrix instance')
    
    
    
    x = Vector(1,8,4)
    
    A = Matrix([1,2,3],
               [3,-2,1])
    y = A * x
    
    y.out()
    
    #単位行列
    I = Matrix([1,0,0],
               [0,1,0],
               [0,0,1])
    
    y = I * x
    y.out()
    
    A = Matrix([0,1],
               [2,3],
               [4,5])
    
    B = Matrix([0,1,2,3],
               [4,5,6,7])
    
    y = A * B
    print(y.matrix)
    
[/code]

実行結果1(__mul__内のprint無し)  
[![画像の説明をここに入力](https://i.stack.imgur.com/H0zHH.jpg)](https://i.stack.imgur.com/H0zHH.jpg)

実行結果2(計算が正しいか確認するため__mul__内にprintを入れた)  
[![画像の説明をここに入力](https://i.stack.imgur.com/o4paD.jpg)](https://i.stack.imgur.com/o4paD.jpg)


CC BY-SA 4.0
2020-11-08T02:04:25.513
71790
2020-11-08T23:00:11.447
2020-11-08T23:00:11.447
4236
41904
question
python 行列
行列×行列の掛け算


以下はサンプル実装です。参考にして下さい。

[code]

    class Vector:
      def __init__(self, *args):
        self.vector = args
    
      def out(self):
        print(self.vector)
    
    class Matrix:
      def __init__(self, *args):
        self.matrix = args
    
      def __mul__(self, tensor):
        if isinstance(tensor, Vector):
          return Vector(
            *[sum(col*tensor.vector[i] for i, col in enumerate(row))
              for row in self.matrix])
        elif isinstance(tensor, Matrix):
          return Matrix(
            *[[sum(a*b for a, b in zip(x, y)) for y in zip(*tensor.matrix)]
              for x in self.matrix])
        else:
          raise TypeError('Not a Vector or Matrix instance')
    
      def out(self):
        print(self.matrix)
    
    if __name__ == '__main__':
      x = Vector(1, 8, 4)
      A = Matrix(
        [1,  2, 3],
        [3, -2, 1],
      )
    
      # 行列×ベクトル
      y = A * x
      y.out()
    
      # 単位行列
      I = Matrix(
        [1, 0, 0],
        [0, 1, 0],
        [0, 0, 1],
      )
    
      # 行列×ベクトル
      y = I * x
      y.out()
    
      # 行列×行列
      A = Matrix(
        [0, 1],
        [2, 3],
        [4, 5],
      )
    
      B = Matrix(
        [0, 1, 2, 3],
        [4, 5, 6, 7],
      )
    
      y = A * B
      y.out()
    
[/code]

**実行結果**

[code]

    (29, -9)
    (1, 8, 4)
    ([4, 5, 6, 7], [12, 17, 22, 27], [20, 29, 38, 47])
    
[/code]

~~> 掛ける側がベクトルか行列かで計算を変える必要があります。

`isinstance()` で `Vector` か `Matrix` 型かを判定して処理を切り替えてみてはどうでしょうか。

[code]

    class Matrix:
      def __init__(self, *args):
        self.matrix = args
    
      def __mul__(self, tensor):
        if isinstance(tensor, Vector):
          return Vector(*[sum([col*tensor.num[i] for i, col in enumerate(row)]) for row in self.matrix])
        elif isinstance(tensor, Matrix):
          return ...
        else:
          raise TypeError('Not a Vector or Matrix instance')
    
[/code]

~~


CC BY-SA 4.0
2020-11-08T02:42:32.403
71791
2020-11-08T15:55:12.853
2020-11-08T15:55:12.853
71790
answer