Multiplying column and row vectors in Numpy - python

I'd like to multiply two vectors, one column (i.e., (N+1)x1), one row (i.e., 1x(N+1)) to give a (N+1)x(N+1) matrix. I'm fairly new to Numpy but have some experience with MATLAB, this is the equivalent code in MATLAB to what I want in Numpy:
n = 0:N;
xx = cos(pi*n/N)';
T = cos(acos(xx)*n');
in Numpy I've tried:
import numpy as np
n = range(0,N+1)
pi = np.pi
xx = np.cos(np.multiply(pi / float(N), n))
xxa = np.asarray(xx)
na = np.asarray(n)
nd = np.transpose(na)
T = np.cos(np.multiply(np.arccos(xxa),nd))
I added the asarray line after I noticed that without it Numpy seemed to be treating xx and n as lists. np.shape(n), np.shape(xx), np.shape(na) and np.shape(xxa) gives the same result: (100001L,)

np.multiply only does element by element multiplication. You want an outer product. Use np.outer:
np.outer(np.arccos(xxa), nd)

If you want to use NumPy similar to MATLAB, you have to make sure that your arrays have the right shape. You can check the shape of any NumPy array with arrayname.shape and because your array na has shape (4,) instead of (4,1), the transpose method is effectless and multiply calculates the dot product. Use arrayname.reshape(N+1,1) resp. arrayname.reshape(1,N+1) to transform your arrays:
import numpy as np
n = range(0,N+1)
pi = np.pi
xx = np.cos(np.multiply(pi / float(N), n))
xxa = np.asarray(xx).reshape(N+1,1)
na = np.asarray(n).reshape(N+1,1)
nd = np.transpose(na)
T = np.cos(np.multiply(np.arccos(xxa),nd))
Since Python 3.5, you can use the # operator for matrix multiplication. So it's a walkover to get code that's very similar to MATLAB:
import numpy as np
n = np.arange(N + 1).reshape(N + 1, 1)
xx = np.cos(np.pi * n / N)
T = np.cos(np.arccos(xx) # n.T)
Here n.T denotes the transpose of n.

Related

Filling a 2D Array (a Matrix)

Consider, for instance, the following formula:
$$f_{nm}(x) = \sin(n \ m \ x^2/\pi)$$
where $n$ and $m$ both are integers $\in [1,4]$. Forming a matrix with this information would result in:
$$\mathbf{F} = \begin{pmatrix}\ f_{11} & f_{12} & f_{13} & f_{14} \\ f_{21} & f_{22} & f_{23} & f_{24} \\ f_{31} & f_{32} & f_{33} & f_{34} \\ f_{41} &f_{42}&f_{43}&f_{44}\end{pmatrix}$$
How to create such a $4\times4$ matrix in Python and fill it with the provided formula for a given $x$ please. I know this question may be off-topic here, but the $LaTeX$ style of the equations did not work for me in the StackOverflow, that is why posted it here.
For a fixed $x$ you should be able to do this
import numpy as np
f = np.zeros((4,4))
for n in range(4):
for m in range(4):
f[n][m] = np.sin(n*m*(x**2)/np.pi)
A faster implementation avoiding Python loops (if I understood your question correctly) that assumes that also x is an array from 0 to 1 and exploits Numpy Broadcasting
import numpy as np
n = np.arange(1, 5)
m = n.reshape(4, 1)
x = np.linspace(0, 1, 100).reshape(100, 1, 1)
result = np.sin(n * m * x**2 / np.pi)
print(result.shape)
This gives a result array of dimensions:
(100, 4, 4)
where the first dimensions indexes the x value. That is:
result[0, ...]
is the 4x4 matrix corresponding to x = x[0] = 0

How do I convert this Matlab code with meshgrid and arrays to Python code?

I am attempting to write a program which constructs a matrix and performs a singular value decomposition on it. I am evaluating the function ax^2 +bx + 1 on a grid. I then make a uniform meshgrid of a and b. The rows of the matrix correspond to different quadratic coefficients, while each column corresponds to a grid point at which the function is evaluated.
The matlab code is here:
% Collect data
x = linspace(-1,1,100);
[a,b] = meshgrid(0:0.1:1,0:0.1:1);
D=zeros(numel(x),numel(a));
sz = size(D)
% Build “Dose” matrix
for i=1:numel(a)
D(:,i) = a(i)*x.^2+b(i)*x+1;
end
% Do the SVD:
[U,S,V]=svd(D,'econ');
D_reconstructed = U*S*V';
plot(diag(S))
scatter3(a(:),b(:),V(:,1))
This is my attempt at a solution:
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
def f(x, a, b):
return a*x*x + b*x + 1
a, b = np.mgrid[0:1:0.1,0:1:0.1]
#a = b = np.arange(0,1,0.01)
D = np.zeros((x.size, a.size))
for i in range(a.size):
D[i] = a[i]*x*x +b[i]*x +1
U, S, V = np.linalg.svd(D)
plt.plot(np.diag(S))
fig = plt.figure()
ax = plt.axes(projection="3d")
ax.scatter(a, b, V[0])
but I always get broadcasting errors which I am not sure how to fix.
Firstly, in MATLAB you're assigning to D(:,i), but in python you're assigning to D[i]. The latter is equivalent to D[i, ...] which is in your case D[i, :]. Instead you seem to need D[:, i].
Secondly, in MATLAB using a linear index into a 2d array (namely a and b) will give you flattened views. If you do that with numpy you get slices of an array instead, just as I mentioned with D[i].
You can do away with the loop with broadcasting and getting your desired 2d array by .ravelling (or reshaping) your a and b arrays:
x = np.linspace(-1, 1, 100)[:, None] # inject trailing singleton for broadcasting
a, b = np.mgrid[0:1:0.1, 0:1:0.1]
D = a.ravel() * x**2 + b.ravel() * x + 1
The way this works is that x has shape (100, 1) after we inject a trailing singleton (in MATLAB trailing singletons are implied, in numpy leading ones), and both a.ravel() and b.ravel() have shape (10*10,) which is compatible with (1, 10*10), making broadcasting possible into shape (100, 10*10). You could also replace the calls to ravel with
a, b = np.mgrid[...].reshape(2, -1)
which is a trick I sometimes use, but this is harder to read if you're unfamiliar with the pattern.
Side note: it's better to use example data where dimensions end up being of different size so that you notice if something ends up being transposed.

Zero Padding a Matrix in Python

I have a 5x20 Matrix, I intend to use Matrix Function and Transformations like Fourier Transform which can only be used for Symmetric Matrix. How can I convert the 5x20 Matrix to 20x20 Matrix by Zero Padding?
import numpy as np
a = np.array([[1,1,1,1],[2,2,2,2]])
b=np.zeros((20,20))
result = np.zeros_like(b)
x = 0
y = 0
result[x:a.shape[0],y:a.shape[1]] = a
print(result)
You can use the above logic to implement the padding.
One more approach.
Here a is the array that you already have.
import numpy as np
a = np.random.rand(5,20)
za = np.zeros((1, 20))
while a.shape[0] < 20:
a = np.concatenate((a,za))
Are you using numpy? If you do you can do it by slicing the arrays
import numpy as np
random_array_5_20 = np.random.rand(5, 20)
padded_array_20_20 = np.zeros((20, 20))
padded_array_20_20[:5, :20] = random_array_5_20

Creating uniform random quaternion and multiplication of two quaternions

I have a python (NumPy) function which creates a uniform random quaternion. I would like to get two quaternion multiplication as 2-dimensional returned array from the same or an another function. The formula of quaternion multiplication in my recent case is Q1*Q2 and Q2*Q1. Here, Q1=(w0, x0, y0, z0) and Q2=(w1, x1, y1, z1) are two quaternions. The expected two quaternion multiplication output (as 2-d returned array) should be
return([-x1*x0 - y1*y0 - z1*z0 + w1*w0, x1*w0 + y1*z0 - z1*y0 +
w1*x0, -x1*z0 + y1*w0 + z1*x0 + w1*y0, x1*y0 - y1*x0 + z1*w0 +
w1*z0])
Can anyone help me please? My codes are here:
def randQ(N):
#Generates a uniform random quaternion
#James J. Kuffner 2004
#A random array 3xN
s = random.rand(3,N)
sigma1 = sqrt(1.0 - s[0])
sigma2 = sqrt(s[0])
theta1 = 2*pi*s[1]
theta2 = 2*pi*s[2]
w = cos(theta2)*sigma2
x = sin(theta1)*sigma1
y = cos(theta1)*sigma1
z = sin(theta2)*sigma2
return array([w, x, y, z])
I know that the question is old but as I found it interesting, for future reference I herewith write an answer: if no special data type for quaternions is desirable, then a quaternion can be written as a tuple of a real number and a normal vector as an array of floats. Thus, mathematically, based on the process mentioned here, the Hamilton product of two quaternions $\hat{q}_1=(w_1,\mathbf{v}_1k$ and $\hat{q}_2=(w_2,\mathbf{v}_2)$ would be:
$$\hat{q}_1 \hat{q}_2=(w_1 w_2-\mathbf{v}^T_1\mathbf{v}_2, w_1 \mathbf{v}_2+w_2 \mathbf{v}_1+\mathbf{v}_1\times \mathbf{v}_2)$$
Sorry for the math notation that cannot be rendered in Stack Overflow.
Thus in numpy:
import numpy as np
q1=(w1,v1)
q2=(w2,v2)
q1q2=(w1*w2-np.matmul(v1.T,v2),w1*v2+w2*v1+np.cross(v1,v2))
A simple rendition of your request would be:
In [70]: def multQ(Q1,Q2):
...: w0,x0,y0,z0 = Q1 # unpack
...: w1,x1,y1,z1 = Q2
...: return([-x1*x0 - y1*y0 - z1*z0 + w1*w0, x1*w0 + y1*z0 - z1*y0 +
...: w1*x0, -x1*z0 + y1*w0 + z1*x0 + w1*y0, x1*y0 - y1*x0 + z1*w0 +
...: w1*z0])
...:
In [72]: multQ(randQ(1),randQ(2))
Out[72]:
[array([-0.37695449, 0.79178506]),
array([-0.38447116, 0.22030199]),
array([ 0.44019022, 0.56496059]),
array([ 0.71855397, 0.07323243])]
The result is a list of 4 arrays. Just wrap it in np.array() to get a 2d array:
In [73]: M=np.array(_)
In [74]: M
Out[74]:
array([[-0.37695449, 0.79178506],
[-0.38447116, 0.22030199],
[ 0.44019022, 0.56496059],
[ 0.71855397, 0.07323243]])
I haven't tried to understand or clean up your description - just rendering it as working code.
A 2-Dimensional Array is an array like this: foo[0][1]
You don't need to do that. Multiplying two quaternions yields one single quaternion. I don't see why you would need a two-dimensional array, or how you would even use one.
Just have a function that takes two arrays as arguments:
def multQuat(q1, q2):
then return the relevant array.
return array([-q2[1] * q1[1], ...])
I know the post is pretty old but would like to add a function using the pyquaternion library to calculate quaternion multiplication. The quaternion multiplication mentioned in the question is called the Hamilton product. You can use it like below...
from pyquaternion import Quaternion
q1 = Quaternion()
q2 = Quaternion()
q1_q2 = q1*q2
You can find more about this library here http://kieranwynn.github.io/pyquaternion/
There is a Python module that adds a quaternion dtype to NumPy.
Please check out the documentation for the quaternion module here.
Here is an example from the documentation. It looks native to the usage of NumPy.
>>> import numpy as np
>>> import quaternion
>>> np.quaternion(1,0,0,0)
quaternion(1, 0, 0, 0)
>>> q1 = np.quaternion(1,2,3,4)
>>> q2 = np.quaternion(5,6,7,8)
>>> q1 * q2
quaternion(-60, 12, 30, 24)
>>> a = np.array([q1, q2])
>>> a
array([quaternion(1, 2, 3, 4), quaternion(5, 6, 7, 8)], dtype=quaternion)
>>> np.exp(a)
array([quaternion(1.69392, -0.78956, -1.18434, -1.57912),
quaternion(138.909, -25.6861, -29.9671, -34.2481)], dtype=quaternion)

How to do the loop along a 3D vector with a known length by python

I have done a point filter programme in a 3D plane, but I need to do a loop along a known 3D normal vector with a known length. Many thanks for the help.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
point = sta[10] #starting points
normal = axe[10] #normal vector
d = -point.dot(normal)
# create x,y
xx, yy = np.meshgrid(np.linspace(-3.,-2.,101), np.linspace(-11.,-10.,101))
# calculate corresponding z
z = (-normal[0] * xx - normal[1] * yy - d) * 1. /normal[2]
f=[]
for i in xrange(len(xx)-1):
for j in xrange(len(xx)-1):
if (xx[i][j]-sta[10][0])**2 + (yy[i][j]-sta[10][1])**2 + (z[i][j]-sta[10][2])**2 > float(rad[0])**2:
xx[i][j]=NaN
yy[i][j]=NaN
z[i][j]=NaN
Since you're using meshgrid and xx, yy and z have the same shape, numpy's broadcasting policy will automatically do what you need. Try this:
invalid = (xx-sta[10,0])**2 + (yy-sta[10,1])**2 + (z-sta[10,2])**2 > float(rad[0])**2
xx[invalid]=np.NaN
yy[invalid]=np.NaN
z[invalid]=np.NaN
It creates a boolean mask invalid which contains True for all entries that satisfy the condition. You can then use this mask to set the corresponding values to NaN.
Note that you can use tuples to index numpy arrays. I.e. myArray[a][b] is equivalent to myArray[a, b].
Also note that I assumed you excluded the last entries by accident. If it was on purpose that you used xrange(len(xx)-1) rather than xrange(len(xx)), it is getting a bit uglier and you have to do it like this:
invalid = (xx[:-1,:-1]-sta[10,0])**2 + (yy[:-1,:-1]-sta[10,1])**2 + (z[:-1,:-1]-sta[10,2])**2 > float(rad[0])**2
xx[:-1,:-1][invalid]=np.NaN
yy[:-1,:-1][invalid]=np.NaN
z[:-1,:-1][invalid]=np.NaN

Categories

Resources