Reputation: 408
Suppose I have a matrix H
of size 4 x 4
, and a vector y of size 4 x 1
, I need to get the results of (h'/norm(h, 'fro')) * y
in Python, where h
is the columns of matrix H
and h
' is the transpose of every column of matrix H
. For example in MATLAB I did it straightforwardly as below:
clear all
clc
H = [0.0937 + 1.5453i, -0.1910 - 0.3741i, 1.4420 + 0.6273i, 0.0518 - 0.4653i; ...
0.8537 + 0.9905i, -0.2910 + 0.0131i, 0.2993 - 0.5929i, 0.6426 + 0.4098i;...
0.3722 - 0.3470i, 0.0449 - 0.2985i, -0.7595 - 0.1346i, -1.2782 + 0.1877i; ...
-0.8256 + 0.5255i, -0.5318 - 0.0624i, -0.5467 - 0.4118i, 0.0772 + 0.9888i];
y = [0.1037 + 0.1302i; 0.3676 - 0.0198i; 0.2380 + 0.2824i; 0.0557 - 0.4222i];
re = [];
for ii = 1 : size(H,2)
nn = H(:,ii);
tt = (nn'/norm(nn,'fro') * y)
re = [re tt]
end
But in Python it gives an error! I gave a try as below:
import numpy as np
h = np.array([[0.0937 + 1.5453j, -0.1910 - 0.3741j, 1.4420 + 0.6273j, 0.0518 - 0.4653j],
[0.8537 + 0.9905j, -0.2910 + 0.0131j, 0.2993 - 0.5929j, 0.6426 + 0.4098j],
[0.3722 - 0.3470j, 0.0449 - 0.2985j, -0.7595 - 0.1346j, -1.2782 + 0.1877j],
[-0.8256 + 0.5255j, -0.5318 - 0.0624j, -0.5467 - 0.4118j, 0.0772 + 0.9888j]])
y = np.array([[0.1037 + 0.1302j], [0.3676 - 0.0198j], [0.2380 + 0.2824j], [0.0557 - 0.4222j]])
n = 3
re= np.zeros((1, 4), dtype=np.complex)
for ii in range(n):
re[:, ii] = ((np.linalg.pinv(h[:, ii])).transpose() / (np.linalg.norm(np.linalg.pinv(h[:, ii]), 'fro'))).dot(y)
But I get an error when running the last command of re[:, ii] = ((np.linalg.pinv(h[:, ii])).transpose() / (np.linalg.norm(np.linalg.pinv(h[:, ii]), 'fro'))).dot(y)
, it says:
numpy.linalg.LinAlgError: 1-dimensional array given. Array must be at least two-dimensional
Upvotes: 0
Views: 659
Reputation: 25043
I executed your Matlab™ code to get these values for re
:
[0.098760-0.009564i, -0.316010+0.408531i, 0.139199+0.203590i, -0.264498-0.323802i]
This Python/Numpy code
import numpy as np
from numpy.linalg import norm
H = np.array(([ 0.0937 + 1.5453j, -0.1910 - 0.3741j, 1.4420 + 0.6273j, 0.0518 - 0.4653j],
[ 0.8537 + 0.9905j, -0.2910 + 0.0131j, 0.2993 - 0.5929j, 0.6426 + 0.4098j],
[ 0.3722 - 0.3470j, 0.0449 - 0.2985j, -0.7595 - 0.1346j, -1.2782 + 0.1877j],
[-0.8256 + 0.5255j, -0.5318 - 0.0624j, -0.5467 - 0.4118j, 0.0772 + 0.9888j]))
y = np.array([0.1037 + 0.1302j, 0.3676 - 0.0198j, 0.2380 + 0.2824j, 0.0557 - 0.4222j])
np.conjugate(H/norm(H, axis=0)).T@y
gives
array([ 0.09875966-0.00956369j, -0.31600998+0.40853066j, 0.13919918+0.20358966j, -0.26449838-0.32380165j])
I think that the main issue here is that transposing a complex array in Matlab™ gives you the transpose conjugate, transposing the same array in Numpy does not perform the conjugation. Another issue is that a mat-vec dot product (the @
operator) is row-column, while you need col-col, so we need a transposition too.
Upvotes: 3
Reputation: 930
Maybe this will do what you want:
Also in your code n
should be equal to 4:
n = 4
for ii in range(n):
tmp1 = (h[:, ii]).transpose()
tmp2 = (np.linalg.norm(h[:, ii].transpose()))
re[:, ii] = (tmp1 / tmp2).dot(y)
Please see if it will achieve the same results as in matlab. I fixed your errors, but I am not sure if that is the correct calculation.
I also deleted the fro
from calculating the norm as linalg.norm()
is using it by default and specifically adding it causes some trouble. For more details see here:
https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.norm.html
Upvotes: 1