difficulty in matlab to python code conversion - python

I am converting matlab code to python code
function Xn = ReSampleCurve(X,N)
[n,T] = size(X);
del(1) = 0;
for r = 2:T
del(r) = norm(X(:,r) - X(:,r-1));
end
cumdel = cumsum(del)/sum(del);
newdel = [0:N-1]/(N-1);
for j=1:n
Xn(j,:) = interp1(cumdel,X(j,1:T),newdel,'linear');
end
I want to convert this into python code
The input values are :
X = [[-9.035250067710876, 7.453250169754028, 33.34074878692627], [-6.63700008392334, 5.132999956607819, 31.66075038909912],[-5.1272499561309814, 8.251499891281128, 30.925999641418457], [-5.1272499561309814, 8.251499891281128, 30.925999641418457]]
N = 200
can anyone explains me what these lines do?
del(1) = 0;
for r = 2:T
del(r) = norm(X(:,r) - X(:,r-1));

For what it is worth, here is the vectorized way to get del(2:end) in Matlab, perhaps this makes more sense to you:
sqrt(sum(diff(M,1,2).^2))

del is an array in the MATLAB code. So del(1) = 0 is equivalent to del_list = [0] (MATLAB arrays a 1-indexed, del is a reserved word in python).
In the for loop, this is equivalent to:
for r in range(1,T):
del_list.append(norm(X[:,r] - X[:,r-1]))
The above won't work in pure python (array subtraction won't work). You'd have to add in numpy or numeric) - but hopefully you get the idea.

Related

How to make code like repmat MATLAB on Python?

This MATLAB code is from Main_MOHHO.m from https://www.mathworks.com/matlabcentral/fileexchange/80776-multi-objective-harris-hawks-optimization-mohho. I want to make the same code using python, but I can't make the Rabbits variabel.
clc;
clear;
close all;
%% Problem Definition
nVar=3; % Number of Decision Variables
VarSize=[1 nVar]; % Size of Decision Variables Matrix
VarMin=0; % Lower Bound of Variables
VarMax=1; % Upper Bound of Variables
nPop=5; % Population Size
%% Initialization
empty_Rabbit.Location=[];
empty_Rabbit.Cost=[];
empty_Rabbit.Sol=[];
empty_Rabbit.IsDominated=[];
empty_Rabbit.GridIndex=[];
empty_Rabbit.GridSubIndex=[];
Rabbits=repmat(empty_Rabbit,nPop,1);
for i=1:nPop
Rabbits(i).Location = rand(VarSize).*(VarMax-VarMin)+VarMin;
X(i,:) = rand(VarSize).*(VarMax-VarMin)+VarMin;
end
I try to make it on google colab like this.
import numpy as np
nVar = 3 # Number of Decision Variables
VarSize = np.array((1, nVar)) # Size of Decision Variables Matrix
VarMin = 0 # Lower Bound of Variables
VarMax = 1 # Upper Bound of Variables
nPop = 5 # Population Size
class empty_Rabbit:
Location = []
Cost = []
IsDominated = []
GridIndex = []
GridSubIndex = []
Sol = []
Rabbits = np.tile(empty_Rabbit, (nPop, 1))
X = np.zeros((nPop, nVar))
Rabbit_Location = np.zeros((VarSize))
Rabbit_Energy = math.inf
for i in range(nPop):
Rabbits[i, 0].Location = np.multiply(np.random.rand(VarSize[0], VarSize[1]),
(VarMax-VarMin) + VarMin)
print(Rabbits[i,0].Location)
But, the Rabbits_Location same for each row.
Output Google Colab
What is the correct way to create Rabbits variable in python so the output like the output with number 1 in the pic? Thank you.
Two issues exist in your code. First, np.tile repeats the same object (nPop, 1) times. So, when you change one of the objects, you actually change the same memory location. Second, you want to initialize a different object each time instead of referring to the same object, so you want to write empty_Rabbit() to create a new instance of that object. Both suggestions can be achieved using a comprehension like [empty_Rabbit() for i in range(nPop)] and reshape to any new dimensions if required.
import numpy as np
nVar = 3 # Number of Decision Variables
VarSize = np.array((1, nVar)) # Size of Decision Variables Matrix
VarMin = 0 # Lower Bound of Variables
VarMax = 1 # Upper Bound of Variables
nPop = 5 # Population Size
class empty_Rabbit:
Location = []
Cost = []
IsDominated = []
GridIndex = []
GridSubIndex = []
Sol = []
Rabbits = np.array([empty_Rabbit() for i in range(nPop)]).reshape(nPop,1)
X = np.zeros((nPop, nVar))
Rabbit_Location = np.zeros((VarSize))
Rabbit_Energy = np.inf
for i in range(nPop):
Rabbits[i, 0].Location = np.multiply(np.random.rand(VarSize[0], VarSize[1]),
(VarMax-VarMin) + VarMin)
print(Rabbits[i,0].Location)
for i in range(nPop):
print(Rabbits[i,0].Location)
Now, the output of both print statements will be identical with distinct rows:
[[0.5392264 0.39375339 0.59483626]]
[[0.53959355 0.91049574 0.58115175]]
[[0.46152304 0.43111977 0.06882631]]
[[0.13693784 0.82075653 0.49488394]]
[[0.06901317 0.34133836 0.91453956]]
[[0.5392264 0.39375339 0.59483626]]
[[0.53959355 0.91049574 0.58115175]]
[[0.46152304 0.43111977 0.06882631]]
[[0.13693784 0.82075653 0.49488394]]
[[0.06901317 0.34133836 0.91453956]]
scipy.io.loadmat uses structured arrays when loading struct from MATLAB .mat files. But I think that's too advanced for you.
I think you need to create a set of numpy arrays, rather than try for some sort of class or more complicated structure.
empty_Rabbit.Location=[];
empty_Rabbit.Cost=[];
empty_Rabbit.Sol=[];
empty_Rabbit.IsDominated=[];
empty_Rabbit.GridIndex=[];
empty_Rabbit.GridSubIndex=[];
becomes instead
location = np.zeros(nPop)
cost = np.zeros(nPop)
sol = np.zeros(nPop)
isDominated = np.zeros(nPop) # or bool dtype?
gridIndex = np.zeros(nPop)
gridSubIndex = np.zeros(nPop)
np.zeros makes a float array; for some of those you might want np.zeros(nPop, dtype=int) (if used as index).
rabbit= np.zeros(nPop, dtype=[('location',float), ('cost',float),('sol',float), ....])
could be used to make structured array, but you'll need to read more about those.
MATLAB lets you use iteration freely as in
for i=1:nPop
Rabbits(i).Location = rand(VarSize).*(VarMax-VarMin)+VarMin;
X(i,:) = rand(VarSize).*(VarMax-VarMin)+VarMin;
end
but that's slow (as it used to be MATLAB before jit compilation). It's better to use whole array calculations
location = np.random.rand(nPop,VarSize) * (VarMax-VarMin)+VarMin
will make a (nPop,VarSize) 2d array, not the 1d that np.zeros(nPop) created.
Looks like X could be created in the same way (without iteration).

Numpy: Get rid of loop in a concrete example

I'm new to Numpy and already read a few things about it. Repeatedly it says, that you should get rid of loops when using Numpy, because otherwise you have some Python-overhead which slows down your code. So for practicing I tried to implement a simple algorithm in a "numpythonic" way, but I can't manage to get rid of the for loop. Is there a way to improve this solution?
My main problem is, that I have some kind of "cumulative-conditional" situation and I have no idea how I can solve this without a loop.
import numpy as np
def process(data):
r = np.zeros(3)
for d in data:
ru = r / np.linalg.norm(r)
r = np.where(
np.dot(ru, d) < 0.0,
r + np.negative(d),
r + d
)
return r
data = [
[0.99558784, 0.03476669, -0.08715574],
[0.99194152, 0.1217951, -0.0348995],
[0.9864998, 0.08630755, -0.1391731]
]
print(process(data))
# Out: [ 2.97402916 0.24286934 -0.26122834]
(Besides of my main problem I'm open for general criticism or improvement suggestions of course)
A few comments:
In first loop, your ru = ... statement produces warning - it divides by 0.
In this case, np.dot() returns a single float, not an array. Hence, there is no point for using np.where(); if statement would be faster.
For the data you provided, your function is equivalent to np.sum(data, axis=0).

Speeding up this code snippet

I am rewriting one code from Matlab to Python.
Matlab code looks like this:
validIntSize = length(prices1)-125; %valid interval size
interval720s = zeros(validIntSize,120+1);
interval360s = zeros(validIntSize,60+1);
interval180s = zeros(validIntSize,30+1);
for i = 1:intJump:validIntSize
interval180s(i,:) = [prices1(i:i+29),priceDiff(i+29)];
interval360s(i,:) = [prices1(i:i+59),priceDiff(i+59)];
interval720s(i,:) = [prices1(i:i+119),priceDiff(i+119)];
end
It populates the rows of this huge matrix in a nutshell. I do this through append in Python and it takes way too long:
intervals = []
for mean in self.means: intervals.append([])
for i in range(stop_point):
for idx, mean in enumerate(self.means):
intervals[idx].append(list(prices1[i:(i+mean)])+[price_diff[i+mean]])
I suspect that this is due to the append method that I am using?
P.S. it takes about 2 seconds in Matlab and about 2 minutes in Python.
P.P.S changing my code to list comprehension as suggested in the comments:
for idx, k_mean in enumerate(self.k_means):
intervals[idx] = [list(prices1[i:(i+k_mean)])+[price_diff[i+k_mean]] for i in range(stop_point)]
does not speed up the code. Takes virtually the same amount of time.

normalization in theano for any image?

I write below code but that is very slow. And, of course, does not work correct!
I have what I do?
for i in range(image_shape[0]):
for j in range(filter_shape[0]):
pmin = self.pooled_out[i][j].min()
pmax = self.pooled_out[i][j].max()
self.pooled_out = T.set_subtensor(T.set_subtensor(self.pooled_out[i], self.pooled_out[i])[j],self.pooled_out[i][j] - pmin)
self.pooled_out = T.set_subtensor(T.set_subtensor(self.pooled_out[i], self.pooled_out[i])[j],self.pooled_out[i][j] / pmax)
First that section of your code do nothing. Just remove this line
T.set_subtensor(self.pooled_out[i], self.pooled_out[i])
Without full code, I can't test my solution, but I think this would do what you want:
pmin = self.pooled_out.min(axis=[2,3], keepdims=True)
pmax = self.pooled_out.max(axis=[2,3], keepdims=True)
normalized_pooled_out = (self.pooled_out - pmin)/pmax
Then normalized_pooled_out contain the symbolic variable that have the value I think you want.

Array operations/ slicing in python from matlab

I have matlab array operations as the following :
[M,N]=size(I) ;
J = zeros(2*M,2*N) ;
J(1:2:end,1:2:end) = I ;
J(2:2:end-1,2:2:end-1) = 0.25*I(1:end-1,1:end-1) + 0.25*I(2:end,1:end-1) + 0.25*I(1:end-1,2:end) + 0.25*I(2:end,2:end) ;
J(2:2:end-1,1:2:end) = 0.5*I(1:end-1,:) + 0.5*I(2:end,:) ;
J(1:2:end,2:2:end-1) = 0.5*I(:,1:end-1) + 0.5*I(:,2:end) ;
I am trying to rewrite the same operations in python and I have come up with the following:
J=numpy.zeros((2*M,2*N))
J[::2,::2] = I ;
J[2:-1:2,2:-1:2] = 0.25*I[1::-1,1::-1] + 0.25*I[2::,1::-1] + 0.25*I[1::-1,2::] + 0.25*I[2::,2::]
J[2:-1:2,1::2] = 0.5*I[1::-1,] + 0.5*I[2::,]
J[::2,2:-1:2] = 0.5*I[:,1::-1] + 0.5*I[:,2::]
however the python code gives me different results.
can anyone tell me what is wrong?
Thanks,
Going through this piece by piece shows that you have some errors in your ranges. I think that you have misunderstood a few things about arrays in python.
Unlike matlab where the first element of an array is array[1], in python the first element of an array is array[0].
Array slicing syntax is array[start:stop:step], so to get every second element starting at the fifth element in the array to the end you would do array[4::2].
Just go through this piece by piece and you will find problems. For example, the first element on the right hand side of the second equation should be:
0.25*I[0:-1, 0:-1]
Note that you don't need the second colon here since your step is 1 and in cases where you want to change the step, the step goes last.
so here is the correct ported code:
J[::2,::2] = I ;
J[1:-1:2,2:-1:2] = 0.25*I[0:-1,0:-1] + 0.25*I[1::,0:-1] + 0.25*I[0:-1,1::] + 0.25*I[1::,1::]
J[1:-1:2,0::2] = 0.5*I[0:-1,] + 0.5*I[1::,]
J[0::2,1:-1:2] = 0.5*I[:,0:-1] + 0.5*I[:,1::]

Categories