0

What is the difference between the calculation in numpy.linalg.matrix_power and directly multiplying the matrix by itself those many times? This is what I observed and was confused about.

>> Matrix A:
[[2 4 5], 
 [4 4 5],
 [8 3 1]]

>> numpy.linalg.matrix_power(A, 3)
[[556 501 530]
 [676 579 600]
 [708 500 471]]

>> (A * A) * A
[[556 501 530]
 [676 579 600]
 [708 500 471]]

But

>> A = normalize(A, axis=1, norm='l1')
[[0.18181818 0.36363636 0.45454545]
 [0.30769231 0.30769231 0.38461538]
 [0.66666667 0.25       0.08333333]]

>> numpy.linalg.matrix_power(A, 3)
[[0.34477471 0.31773179 0.3374935],
[0.36065187 0.31371769 0.32563044],
[0.42154896 0.2984543  0.27999674]]

>> (A * A) * A
[[0.00601052 0.04808415 0.09391435]
 [0.02913063 0.02913063 0.05689577]
 [0.2962963  0.015625   0.0005787 ]]

Why are the results different? Which one is the correct (expected) computation?

This is the simple code I am checking

import numpy as np

A = np.matrix([[2, 4, 5], [4, 4, 5], [8, 3, 1]])
#A = normalize(A, axis=1, norm='l1') #uncommented for the 2nd part

print(A)
print(np.linalg.matrix_power(A, 3))
print((A * A) * A)
ad123
  • 37
  • 6
  • 2
    Matrix multiplication is not `A * B` but rather `A @ B`. The first performs `element wise` multiplication the second is `sum(row * column)`. So `numpy.linalg.matrix_power(A, 3)` is the same as `A @ A @ A` – scleronomic Jan 22 '20 at 11:42
  • 1
    The first `(A * A) * A` gives me a completely different result. Please, check again. – Georgy Jan 22 '20 at 11:50
  • Was `A` a `np.matrix` class? Is the second still that? – hpaulj Jan 22 '20 at 13:10

1 Answers1

0
In [1]: from sklearn.preprocessing import normalize  

Start with a numpy array:

In [2]: A = np.array([[2,4,5],[4,4,5],[8,3,1]])                                                  

make a np.matrix from it:

In [3]: M = np.matrix(A)                                                                         
In [4]: A                                                                                        
Out[4]: 
array([[2, 4, 5],
       [4, 4, 5],
       [8, 3, 1]])
In [5]: M                                                                                        
Out[5]: 
matrix([[2, 4, 5],
        [4, 4, 5],
        [8, 3, 1]])

* is element-wise for A:

In [6]: (A*A)                                                                                    
Out[6]: 
array([[ 4, 16, 25],
       [16, 16, 25],
       [64,  9,  1]])

But matrix multiplication for M:

In [7]: M*M                                                                                      
Out[7]: 
matrix([[60, 39, 35],
        [64, 47, 45],
        [36, 47, 56]])
In [8]: A@A                      # also np.dot(A,A)                                                                   
Out[8]: 
array([[60, 39, 35],
       [64, 47, 45],
       [36, 47, 56]])

Pass M through normalize:

In [9]: N = normalize(M)                                                                         
In [10]: N                                                                                       
Out[10]: 
array([[0.2981424 , 0.59628479, 0.74535599],
       [0.52981294, 0.52981294, 0.66226618],
       [0.92998111, 0.34874292, 0.11624764]])

The result is numpy array, not Matrix. So N*N will be elementwise.

Confusion like is part of why np.matrix is no longer recommended.

hpaulj
  • 221,503
  • 14
  • 230
  • 353