Two consecutive parentheses after name in Matlab - python

Please excuse me for this amateurish question,
I'm trying to convert some Matlab code to Python, I don't have any experience with Matlab but so far I have been able to deduce what the Matlab code does and the conversion so far has been successful.
But now I am stuck at these lines of code;
SERAstart = []
for n=1:length(bet)
alf = -bet(n) * 1e-2;
SERAstart = [SERAstart(alf - i * bet(n))(alf + i * bet(n))];
end
What I don't understand is this line;
SERAstart(alf - i * bet(n))(alf + i * bet(n))
Two consecutive parentheses after "SERAstart", are they nested array indexing? are they indexing and then function call to return of indexing? are they function call and then function call again to return value of first call?
Please help me understand what is going on here so that I can convert it to Python.
I realize that it might not be possible just from the piece of code I have posted to say definitively what it does, but otherwise if you can help guide me to how to figure it out (without the use of Matlab) then I would also be very grateful.
Thanks a lot for any help!.
EDIT:
This is my own attempt at a conversion, but I don't know if this makes sense;
# SERAstart = [];
SERAstart = [[]]
# for n=1:length(bet)
for n in range(len(bet)):
# alf = -bet(n) * 1e-2;
alf = -bet[n] * 1e-2
# SERAstart = [SERAstart(alf - i * bet(n))(alf + i * bet(n))];
SERAstart = [SERAstart[alf - 1j * bet[n]][alf + 1j * bet[n]]]
# end
EDIT2:
I just noticed this line in the documentation relating to SERAstart:
% SERAstart(N,1) : vector of starting poles [rad/sec]

Related

Issue with jax.lax.scan

I am supposed to use Jax.lax.scan instead of a for loop with 100 iterations at line 22. I am supposed to update S and append it to S_list. I am unsure how to fix the jax.lax.scan. The error that keeps popping up is missing the required XS. When I put a value for XS it says that my length argument doesn't line up with the axis sizes. Here is my code. Can you help me?
You're not calling scan with the correct signature. You can find more information on the call signature in the jax.lax.scan docs. It makes clear, for example, that your step function must accept two arguments and return two arguments.
From looking at your code, it looks like you're intending to do something like this:
#jax.jit
def simulate():
key = jax.random.PRNGKey(0)
def step(S, _):
dZ = jax.random.normal(key, shape=(S.size,)) * jnp.sqrt(dt)
dS = r * S * dt + σ * S * dZ
return S + dS, S
S0 = jnp.ones(20000)
_, S_array = jax.lax.scan(step, S0, xs=None, length=m)
return S_array
In particular, from the docs you can see that the S_list.append(...) and S_array = jnp.stack(S_list) are effectively part of the scan function itself, so you don't have to do that yourself after calling it.
Hope that helps!

I'm new in python, how to solve my code problem of TypeError: missing 2 required positional arguments & TypeError: 'list' object is not callable

I write this function of "Euler2quat" in python, it seems okay but when I call it to perform the conversion in this line "q0123_0 = Euler2quat([ptp0])" of my code I received this TypeError: Euler2quat() missing 2 required positional arguments: 'theta' and 'psi'.... I tried to define them like this also.
def Euler2quat(phi_theta_psi):
phi = phi_theta_psi(1)
theta = phi_theta_psi(2)
psi = phi_theta_psi(3)
but still, have another new error: TypeError: 'list' object is not callable
it's my first time using python, I need help with this thanks in advance.
here is the code.
import numpy as np
import matplotlib.pyplot as plt
import scipy.integrate as sci
def Euler2quat(phi, theta, psi):
q0 = np.cos(phi/2) * np.cos(theta/2) * np.cos(psi/2) + np.sin(phi/2) * np.sin(theta/2) * np.sin(psi/2)
q1 = np.sin(phi/2) * np.cos(theta/2) * np.cos(psi/2) - np.cos(phi/2) * np.sin(theta/2) * np.sin(psi/2)
q2 = np.cos(phi/2) * np.sin(theta/2) * np.cos(psi/2) + np.sin(phi/2) * np.cos(theta/2) * np.sin(psi/2)
q3 = np.cos(phi/2) * np.cos(theta/2) * np.sin(psi/2) - np.sin(phi/2) * np.sin(theta/2) * np.cos(psi/2)
return[q0,q1,q2,q3]
## Initial conditions for Attitude and Angular velocity
phi0 = 0
theta0 = 0
psi0 = 0
ptp0 = np.asarray([[phi0],[theta0],[psi0]])
q0123_0 = Euler2quat([ptp0])
import numpy as np
# import matplotlib.pyplot as plt
# import scipy.integrate as sci
def Euler2quat(ptp):
phi, theta, psi = ptp
q0 = np.cos(phi / 2) * np.cos(theta / 2) * np.cos(psi / 2) + np.sin(phi / 2) * np.sin(theta / 2) * np.sin(psi / 2)
q1 = np.sin(phi / 2) * np.cos(theta / 2) * np.cos(psi / 2) - np.cos(phi / 2) * np.sin(theta / 2) * np.sin(psi / 2)
q2 = np.cos(phi / 2) * np.sin(theta / 2) * np.cos(psi / 2) + np.sin(phi / 2) * np.cos(theta / 2) * np.sin(psi / 2)
q3 = np.cos(phi / 2) * np.cos(theta / 2) * np.sin(psi / 2) - np.sin(phi / 2) * np.sin(theta / 2) * np.cos(psi / 2)
return [q0, q1, q2, q3]
## Initial conditions for Attitude and Angular velocity
phi0 = 0
theta0 = 0
psi0 = 0
ptp0 = np.asarray([[phi0], [theta0], [psi0]])
q0123_0 = Euler2quat(ptp0)
Your second error is because you can't call lists like functions. What are you trying to do there, get the items of the list into separate variables? Indexing uses [] and furthermore, list indexes start at 0.
def Euler2quat(phi_theta_psi):
phi = phi_theta_psi[0]
theta = phi_theta_psi[1]
psi = phi_theta_psi[2]
But the more Pythonic way to write it is to use unpacking:
phi, theta, psi = phi_theta_psi
Euler2quat function requires 3 arguments, phi, theta and psi. You are calling it as Euler2quat([ptp0]), which means passing just one argument, a list with one element, ptp0.
You should call Euler2quat(phi0,theta0,psi0) instead.
Also, as mentioned by #stian-larsen, when accessing lists you should use squared brackets.
As pointed out by #Trenomarcus, your function requires 3 arguments, the code below should work:
q0123_0 = Euler2quat(*ptp0)
Adding * before the name of the array unpacks it and passes each element to each argument.
phi_theta_psi(1) i a Tuple, not a list. try using squared brackets instead, like this: phi_theta_psi[1]. Happy coding
The solution to both problems is pretty simple and the maths seems sound.
The reason your initial Euler2quat function wasn't working because the function takes 3 arguments (phi, theta and psi), each of which are different objects.
Note: arrays are called lists in python (outside of libraries such as numpy), so I will be referring to them as lists for the entirety of this answer.
You tried to call this function with a list/array (ptp0), but a list is considered as one object. A list is a just a collection of data (in your case, numerical data) but it can also be considered as 1 piece of data (sequential data) which can be indexed as I think you tried to do with your psi_theta_psi(1). When indexed, it needs to be indexed with square brackets ([]) rather than circular ones, since circular brackets are used for calling functions and classes whilst square brackets are used for indexing and slicing. Your corrected function wouldn't have worked for a few other reasons, but the square brackets would remove the TypeError: 'list' object is not callable error.
To remove the original error, just call Euler2quat like so: Euler2quat(psi0, theta0, psi0) or if you need to use php0 to call the function, you can use Euler2quat(*php0). This works because * can be used to unpack iterators (i.e. to return all objects inside one object (such as a list object) as multiple objects), and Euler2quat requires 3 objects in it's arguments. Using Euler2quat([php0]) doesn't work because it still calls on the function with 1 argument, which is a list containing php0. Putting one list inside another list doesn't unpack it, it just creates a list of lists (i.e. a 2d array). Also when using return in a function it's best to use it with a space between it and the data it returns.
The function from your second try wouldn't have worked for many reasons as I said above, the first reason being that it creates a completely new function for Euler2quat which only tries to unpack lists and completely overrides the original. I think what you wanted to do was to create something similar to a decorator function, but giving that function the same name as one which already exists means essentially deleting and replacing the function which already exists with that name. Secondly, when indexing lists, the first value in a list has an index of 0 and the last has an index of it's length - 1 (this is a python thing), meaning that all phi_theta_psi[n] (where n represents the index number you used) lines would need to be changed to phi_theta_psi[n-1].
Lastly, python is all about readability so I don't recommend putting a 0 at the end of all your variable names (because it isn't necessary), and names like q0123_0 or Euler2quat don't promote readability.
I suggest doing some more learning on python, because your code is riddled with errors and you need to learn a programming language's rules and syntax before using it, similarly to how you would with a verbal language like Spanish. Python may be the easiest language to learn, but you can't expect to type anything and for it to work.
Thank you for coming to my Ted Talk.

MATLAB Size equivalent function in python

hI i have a code in matlab. Based on my understanding I have translated that code to python. Can someone let me know if it is the right way to translate.
for i = 1:length(Filters)
Filters{i} = gpuArray(2*(single(sign(Filters{i}))-0.5));
NumLearntWeightsEachLayer(i) = size(Filters{i},3)*size(Filters{i},4)*4;
end
NumLearntWeightsEachLayer(end) = size(Filters{end},3)*size(Filters{end},4);
NumLearntWeightsEachLayer
TotalLearntWeights = sum(NumLearntWeightsEachLayer)
Could someone let me know if this could be an equivalent code for the for loop here.
for i in range (1,Filters):
Filters(i) = (2* (Filters(i) - 0.5))
NumLearntWeightsEachLayer(i) = (Filters(i),3).shape * (Filters(i),4).shape *4
I also want to know what could be the right translation for the last part of the code
NumLearntWeightsEachLayer(end) = size(Filters{end},3)*size(Filters{end},4);
It's a good start.. some small fixes -
for i in range (0,len(Filters)):
for j in range(0, len(Filters[i]):
Filters[i][j] = 2*(round(Filters[i][j],1) - 0.5)
NumLearntWeightsEachLayer[i] = len(Filters[i][3])*len(Filters[i][4])*4
For the last line-
NumLearntWeightsEachLayer(end) = size(Filters{end},3)*size(Filters{end},4);
It can be written as -
NumLearntWeightsEachLayer[-1] = len(Filters[-1][3])*len(Filters[-1][4]);

Efficient way to iterate through numpy arrays in parallel and create a new resultant array

I have 3 numpy arrays dm_w, dm_s and dm_p. I am in need of iterating through these arrays in parallel, do some computation based on a check condition as shown in code below.
My code works well for smaller arrays, but takes too long with larger arrays. I need an efficient and faster method to achieve this. Need some expert opinion.
My code:
prox_mat = []
for w_dist, s_dist, PI in zip(np.nditer(dm_w), np.nditer(dm_s), np.nditer(dm_p)):
if PI == 0.0:
proximity_score = ((w_dist + len(np.unique(dm_s) * s_dist)) /
(dm_w.shape[0] * len(np.unique(dm_s))))
prox_mat.append(proximity_score)
else:
proximity_score = ((w_dist + len(np.unique(dm_s) * s_dist)) /
(dm_w.shape[0] * len(np.unique(dm_s)))) * log10(10 * PI)
prox_mat.append(proximity_score)
ps = np.array(prox_mat)
ps = np.reshape(ps, dm_w.shape)
Several things. One, computation of np.unique(dm_s) should be pulled outside of the loop. Even further, it looks like:
len(np.unique(dm_s) * s_dist) == len(np.unique(dm_s))
Which should either be pulled out of the loop or is a mistake. In any case..
We should just vectorize the forloop/append construct:
dm_s_uniques = len(np.unique(dm_s))
logs = np.log10(10 * dm_p)
logs[logs == -np.inf] = 1
prox_mat = ((dm_w + dm_s_uniques) / (dm_w.shape[0] * dm_s_uniques)) * logs
ps = np.reshape(ps, dm_w.shape)
It looks like I map

Is vectorizing this triple for loop in Python / Numpy possible?

I am trying to speed up my code which currently takes a little over an hour to run in Python / Numpy. The majority of computation time occurs in the function pasted below.
I'm trying to vectorize Z, but I'm finding it rather difficult for a triple for loop. Could I possible implement the numpy.diff function somewhere? Take a look:
def MyFESolver(KK,D,r,Z):
global tdim
global xdim
global q1
global q2
for k in range(1,tdim):
for i in range(1,xdim-1):
for j in range (1,xdim-1):
Z[k,i,j]=Z[k-1,i,j]+r*q1*Z[k-1,i,j]*(KK-Z[k-1,i,j])+D*q2*(Z[k-1,i-1,j]-4*Z[k-1,i,j]+Z[k-1,i+1,j]+Z[k-1,i,j-1]+Z[k-1,i,j+1])
return Z
tdim = 75 xdim = 25
I agree, it's tricky because the BCs on all four sides, ruin the simple structure of the Stiffness matrix. You can get rid of the space loops as such:
from pylab import *
from scipy.sparse.lil import lil_matrix
tdim = 3; xdim = 4; r = 1.0; q1, q2 = .05, .05; KK= 1.0; D = .5 #random values
Z = ones((tdim, xdim, xdim))
#Iterate in time
for k in range(1,tdim):
Z_prev = Z[k-1,:,:] #may need to flatten
Z_up = Z_prev[1:-1,2:]
Z_down = Z_prev[1:-1,:-2]
Z_left = Z_prev[:-2,1:-1]
Z_right = Z_prev[2:,1:-1]
centre_term = (q1*r*(Z_prev[1:-1,1:-1] + KK) - 4*D*q2)* Z_prev[1:-1,1:-1]
Z[k,1:-1,1:-1]= Z_prev[1:-1,1:-1]+ centre_term + q2*(Z_up+Z_left+Z_right+Z_down)
But I don't think you can get rid of the time loop...
I think the expression:
Z_up = Z_prev[1:-1,2:]
makes a copy in numpy, whereas what you want is a view - if you can figure out how to do this - it should be even faster (how much?)
Finally, I agree with the rest of the answerers - from experience, this kind of loops are better done in C and then wrapped into numpy. But the above should be faster than the original...
This looks like an ideal case for Cython. I'd suggest writing that function in Cython, it'll probably be hundreds of times faster.

Categories

Resources