Move from Matlab to Python numpy - python

I am new to python so by gentle with me , I try to convert code from Matlab to numpy python , I am working with matrix .
I have some basic question (that I didn't found the answers in Google):
What is the equivalent for the ' tag for example : H' , H= H*H'
What is the equivalent for the / (mrdivide) tag for example : H= H/A
Thanks,
MAK

' (transpose) means the conjugate transpose of a matrix. For real matrices, it is given by np.transpose(arr) or the shorthand arr.T. For complex matrices, you need to use more complicated arr.conj().T.
/ (mrdivide) solves the equation x A = b -> x = b / A using least squares (np.linalg.lstsq). This is equivalent to (x A)^T = b^T -> A^T x^T = b^T, which can be done using np.linalg.lstsq(A.T, b.T).T.

Related

Sympy subs does not working for subexpression. Is there a way to solve this?

subs (from sympy library in Python) does not replace a subexpression in all cases except simple ones. MATLAB copes with this task perfectly. Is it possible to somehow achieve the same result as in MATLAB?
Sympy
MATLAB
This fails because the product 2*(x + y) automatically expands to the sum of 2x + 2*y, as #hpaulj points out. And #oscarbenjamin points out that re-arranging your substitution so it targets only an atomic part of the expression you desire to replace will work.
In addition, if you backsubstitute to restore the original atom you will see if the substitution was not able to be fully done while retaining the original variables:
>>> f = (x + y)**2 + 1/(4*x + 4*y + sin(2*x + 2*y))
>>> (f+x).subs(x,z-y).subs(y,z-x)
x + z**2 + 1/(4*z + sin(2*z))

How to select a component of a sympy equation?

I would like to know if it is possible to select the compotent of a given term of an equation. For example in the photo below. I got that result for a tensor component and I wanna know if it is possible for me to get only the coefficient of the term that accompanies the (e-1)^4 (without having to copy it by hand).
Use the coeff method:
>>> eq = 3*y*(1 - x)**4 + 2*y*(1 - x)
>>> eq.coeff((1-x)**4)
3*y

Conjugate transpose of self using numpy syntax

I am trying to translate this MATLAB code into Python.
The following is the code:
Y=C*Up(:,1:p-1)'*Y;
And this is my translation thus far:
Y = C * Up[:, 1:p-1] * Y
I am having trouble with the syntax for the conjugate transpose of self that is used in the MATLAb code. I am not certain that my first idea:
Y = C * Up[:, 1:p-1].getH() * Y
would be correct.
Does anyone have any ideas?
I am not very experienced with numpy, but based on the comments of #hpaulj I can suggest the following:
If you don't want to be subject to the limitations of numpy.matrix objects (see warning here), you can define your own function for doing a conjugate transpose. All you need to do is transpose your array, then subtract the imaginary part of the result, times 2, from the result. I am not sure how computationally efficient this is, but it should definitely give the correct result.
I'd expect something like this to work:
Y = C * ctranspose(Up[:, 0:p-1]) * Y
...
def ctranspose(arr: np.ndarray) -> np.ndarray:
# Explanation of the math involved:
# x == Real(X) + j*Imag(X)
# conj_x == Real(X) - j*Imag(X)
# conj_x == Real(X) + j*Imag(X) - 2j*Imag(X) == x - 2j*Imag(X)
tmp = arr.transpose()
return tmp - 2j*tmp.imag
(Solution is for Python 3)
A more elegant solution based on the comment by #AndrasDeak:
Y = C * Up[:, 0:p-1].conj().T * Y
Note also, two differences related to indexing between python and MATLAB:
Python is 0-based (i.e. the first index of an array is 0, unlike in MATLAB where it's 1)
The indexing in Python is inclusive:exclusive unlike in MATLAB where it's inclusive:inclusive.
Therefore, when we want to access the first 3 elements of a vector in MATLAB we'd write:
res = vec(1:3);
In Python we'd write:
res = vec[0:3] # or [:3]
(Again, credits to #Andras for this explanation)
Use arr.conj().T to get complex conjugate of a matrix.

MATLAB matrix^-0.5 equivalent in Python

I suggested it could be
np.linalg.inv(np.sqrt(matrix))
but having compared result with MATLAB I saw big difference:
This was in MATLAB
0.2622 -0.0828 -0.0708
-0.0828 0.2601 -0.0792
-0.0708 -0.0792 0.2664
And this was in Python:
0.8607 -0.4417 -0.3536
-0.4417 0.8967 -0.4158
-0.3536 -0.4158 0.8525
Input was
34.502193 27.039107 24.735074
27.039107 36.535737 26.069613
24.735074 26.069613 32.798584
There is no "matrix" class in python. From your code it looks you're talking about numpy.
A possible gotcha for matlab users is that in numpy array operations are elementwise by default, and if you want matrix operations, you need to request them: np.dot for matrix multiplications, np.linalg.inv for inversion etc.
np.linalg.inv(np.sqrt(a)) first takes the square root of each element of a, and then inverts the result in the linear algebra sense. I suspect this is not what you meant to mean.
If you meant elementwise operations, i.e. you wanted to raise each element to power -1/2, then like #Benoit_11 suggests, use
1 / np.sqrt(a).
If what you want is actually a linear algebra operation, then use scipy.linalg.sqrtm
In [14]: a
Out[14]:
array([[ 34.502193, 27.039107, 24.735074],
[ 27.039107, 36.535737, 26.069613],
[ 24.735074, 26.069613, 32.798584]])
In [15]: from scipy.linalg import sqrtm
In [16]: sq = sqrtm(a)
In [17]: np.dot(sq, sq) - a
Out[17]:
array([[ 4.97379915e-14, 4.97379915e-14, 2.84217094e-14],
[ 5.32907052e-14, 6.39488462e-14, 4.61852778e-14],
[ 3.55271368e-14, 3.19744231e-14, 3.55271368e-14]])
It looks like using Python you calculated the inverse of the square root of the matrix (sounds weird sorry) instead of raising the matrix to the power -0.5.
For instance, running this command with Matlab I get your output with python:
m = [34.502193 27.039107 24.735074
27.039107 36.535737 26.069613
24.735074 26.069613 32.798584]
A = inv(sqrt(m))
A =
0.8608 -0.4417 -0.3537
-0.4417 0.8967 -0.4159
-0.3537 -0.4159 0.8525
versus this:
B = m^(-.5)
B =
0.2622 -0.0828 -0.0708
-0.0828 0.2601 -0.0792
-0.0708 -0.0792 0.2664
For the correct Python code please look at #ev-br's answer
Beware that there is such a thing as the matrix square root, which for a matrix M is defined as:
A*A = M
and does not correspond at all to the square root of each element in the matrix M taken individually. The matrix square root is obtained in Matlab using the sqrtm function and is equivalent to m^(.5).

mrdivide function in MATLAB: what is it doing, and how can I do it in Python?

I have this line of MATLAB code:
a/b
I am using these inputs:
a = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9]
b = ones(25, 18)
This is the result (a 1x25 matrix):
[5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
What is MATLAB doing? I am trying to duplicate this behavior in Python, and the mrdivide documentation in MATLAB was unhelpful. Where does the 5 come from, and why are the rest of the values 0?
I have tried this with other inputs and receive similar results, usually just a different first element and zeros filling the remainder of the matrix. In Python when I use linalg.lstsq(b.T,a.T), all of the values in the first matrix returned (i.e. not the singular one) are 0.2. I have already tried right division in Python and it gives something completely off with the wrong dimensions.
I understand what a least square approximation is, I just need to know what mrdivide is doing.
Related:
Array division- translating from MATLAB to Python
MRDIVIDE or the / operator actually solves the xb = a linear system, as opposed to MLDIVIDE or the \ operator which will solve the system bx = a.
To solve a system xb = a with a non-symmetric, non-invertible matrix b, you can either rely on mridivide(), which is done via factorization of b with Gauss elimination, or pinv(), which is done via Singular Value Decomposition, and zero-ing of the singular values below a (default) tolerance level.
Here is the difference (for the case of mldivide): What is the difference between PINV and MLDIVIDE when I solve A*x=b?
When the system is overdetermined, both algorithms provide the
same answer. When the system is underdetermined, PINV will return the
solution x, that has the minimum norm (min NORM(x)). MLDIVIDE will
pick the solution with least number of non-zero elements.
In your example:
% solve xb = a
a = [1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9];
b = ones(25, 18);
the system is underdetermined, and the two different solutions will be:
x1 = a/b; % MRDIVIDE: sparsest solution (min L0 norm)
x2 = a*pinv(b); % PINV: minimum norm solution (min L2)
>> x1 = a/b
Warning: Rank deficient, rank = 1, tol = 2.3551e-014.
ans =
5.0000 0 0 ... 0
>> x2 = a*pinv(b)
ans =
0.2 0.2 0.2 ... 0.2
In both cases the approximation error of xb-a is non-negligible (non-exact solution) and the same, i.e. norm(x1*b-a) and norm(x2*b-a) will return the same result.
What is MATLAB doing?
A great break-down of the algorithms (and checks on properties) invoked by the '\' operator, depending upon the structure of matrix b is given in this post in scicomp.stackexchange.com. I am assuming similar options apply for the / operator.
For your example, MATLAB is most probably doing a Gaussian elimination, giving the sparsest solution amongst a infinitude (that's where the 5 comes from).
What is Python doing?
Python, in linalg.lstsq uses pseudo-inverse/SVD, as demonstrated above (that's why you get a vector of 0.2's). In effect, the following will both give you the same result as MATLAB's pinv():
from numpy import *
a = array([1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9])
b = ones((25, 18))
# xb = a: solve b.T x.T = a.T instead
x2 = linalg.lstsq(b.T, a.T)[0]
x2 = dot(a, linalg.pinv(b))
TL;DR: A/B = np.linalg.solve(B.conj().T, A.conj().T).conj().T
I did not find the earlier answers to create a satisfactory substitute, so I dug into Matlab's reference documents for mrdivide further and found the solution. I cannot explain the actual mathematics here or take credit for coming up with the answer. I'm just following Matlab's explanation. Additionally, I wanted to post the actual detail from Matlab to give credit. If it's a copyright issue, someone tell me and I'll remove the actual text.
%/ Slash or right matrix divide.
% A/B is the matrix division of B into A, which is roughly the
% same as A*INV(B) , except it is computed in a different way.
% More precisely, A/B = (B'\A')'. See MLDIVIDE for details.
%
% C = MRDIVIDE(A,B) is called for the syntax 'A / B' when A or B is an
% object.
%
% See also MLDIVIDE, RDIVIDE, LDIVIDE.
% Copyright 1984-2005 The MathWorks, Inc.
Note that the ' symbol indicates the complex conjugate transpose. In python using numpy, that requires .conj().T chained together.
Per this handy "cheat sheet" of numpy for matlab users, linalg.lstsq(b,a) -- linalg is numpy.linalg.linalg, a light-weight version of the full scipy.linalg.
a/b finds the least square solution to the system of linear equations bx = a
if b is invertible, this is a*inv(b), but if it isn't, the it is the x which minimises norm(bx-a)
You can read more about least squares on wikipedia.
according to matlab documentation, mrdivide will return at most k non-zero values, where k is the computed rank of b. my guess is that matlab in your case solves the least squares problem given by replacing b by b(:1) (which has the same rank). In this case the moore-penrose inverse b2 = b(1,:); inv(b2*b2')*b2*a' is defined and gives the same answer

Categories