First, I used np.array
to perform operations on multiple matrices, and it was successful.
import numpy as np
import matplotlib.pyplot as plt
f = np.array([[0.35, 0.65]])
e = np.array([[0.92, 0.08], [0.03, 0.97]])
r = np.array([[0.95, 0.05], [0.06, 0.94]])
d = np.array([[0.99, 0.01], [0.08, 0.92]])
c = np.array([[0, 1], [1, 0]])
D = np.sum(f@(e@r@d*c))
u = f@e
I = np.sum(f@(e*np.log(e/u)))
print(D)
print(I)
Outcome:
0.14538525
0.45687371996485304
Next, I tried to plot the result using one of the elements in the matrix as a variable, but an error occurred.
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.01, 0.99, 0.01)
f = np.array([[0.35, 0.65]])
e = np.array([[1-t, t], [0.03, 0.97]])
r = np.array([[0.95, 0.05], [0.06, 0.94]])
d = np.array([[0.99, 0.01], [0.08, 0.92]])
c = np.array([[0, 1], [1, 0]])
D = np.sum(f@(e@r@d*c))
u = f@e
I = np.sum(f@(e*np.log(e/u)))
plt.plot(t, D)
plt.plot(t, I)
plt.show()
It shows the error below:
AttributeError Traceback (most recent call last)
AttributeError: 'numpy.ndarray' object has no attribute 'log'
The above exception was the direct cause of the following exception:
TypeError Traceback (most recent call last)
<ipython-input-14-0856df964382> in <module>()
10
11 u = f@e
---> 12 I = np.sum(f@(e*np.log(e/u)))
13
14 plt.plot(t, D)
TypeError: loop of ufunc does not support argument 0 of type numpy.ndarray which has no callable log method
There was no problem with the following code, so I think there was something wrong with using np.array
.
import numpy as np
import matplotlib.pyplot as plt
t = np.arange(0.01, 0.99, 0.01)
y = np.log(t)
plt.plot(t, y)
plt.show()
Any idea for this problem? Thank you very much.
You can't create a batch of matrices e
from the variable t
using the construct
e = np.array([[1-t, t], [0.03, 0.97]])
as this would create a ragged array due to [1-t, t]
and [0.03, 0.97]
having different shapes. Instead, you can create e
by repeating [0.03, 0.97]
to match the shape of [1-t, t]
, then stack them together as follows.
t = np.arange(.01, .99, .01) # shape (98,)
_t = np.stack([t, 1-t], axis=1) # shape (98, 2)
e = np.array([[.03, .97]]) # shape (1, 2)
e = np.repeat(e, len(ts), axis=0) # shape (98, 2)
e = np.stack([_t, e], axis=1) # shape (98, 2, 2)
After this, e
will be a batch of 2x2 matrices
array([[[0.01, 0.99],
[0.03, 0.97]],
[[0.02, 0.98],
[0.03, 0.97]],
[[0.03, 0.97],
[0.03, 0.97]],
[[0.04, 0.96],
[0.03, 0.97]], ...
Finally, expand other variables in the batch dimension to take advantage of numpy broadcast to batch the calculation
f = np.array([[0.35, 0.65]])[None,:] # shape (1,1,2)
r = np.array([[0.95, 0.05], [0.06, 0.94]])[None,:] # shape (1,2,2)
d = np.array([[0.99, 0.01], [0.08, 0.92]])[None,:] # shape (1,2,2)
c = np.array([[0, 1], [1, 0]])[None,:] # shape (1,2,2)
and only sum across the last axis to get per-matrix result.
D = np.sum(f@(e@r@d*c), axis=-1) # shape (98, 1)
u = f@e
I = np.sum(f@(e*np.log(e/u)), axis=-1) # shape (98, 1)