Convert Matlab code to Python code using proper syntax - python

I have this simple piece of Matlab code below I like to convert over to Python.What is the correct Python syntax for the last line? I have also posted my Python attempt below this little snippet.
%variables
x=\[1 2 3 4 5 6\]
l_Vector =5
memlen = 2
deg =2
n= 1
k=1
% create 5 x 4
x_val = np.zeros( (l_Vector,memlen\*deg) )
x_val(n,(k - 1)*memlen+(1:memlen)) = (x(n:(n + memlen-1)).*(abs(x(n:(n + memlen -1))).^(k - 1))).';
type here
I tried the following : breaking the last line down.
from scipy import linalg
import numpy as np
x= np.array([1,2,3,4,5,6])
l_Vector =5
memlen = 2
deg =2
x_terms = np.zeros( (l_Vector,memlendeg) )
term_1 = x[n:(n+memorylen)]
term_2 = np.abs(x[n:(n+memorylen)])**k
pp = np.multiply(term_1 ,term_2)
x_terms[n,(k)(memorylen) ,2] = pp.T

Related

How to load data as a matrix (using csv file) into python?

I would like to solve an LPP (Max CX s.to. AX<=B, X>=0) using pyomo, I have loaded the data for C, and B. However I tried to load the matrix A but after solving the model it does not show the correct answer. The code that I tried is in the following lines. Please suggest how to solve this type of problem in pyomo.
from pathlib import Path
from pyomo.environ import *
import pandas as pd
import numpy as np
path_model_in_set = Path('tmp/input/set')
path_model_in_par = Path('tmp/input/par')
path_model_out = Path('tmp/output')
path_results = Path('tmp/output')
m = AbstractModel('LPP')
#Set
m.a = Set(ordered=True, doc="indices for row")
m.b = Set(ordered=True, doc="indices for column")
#Parameters
m.A = Param(m.a, m.b, mutable=True, initialize=0, doc="Matrix")
m.B = Param(m.a, doc="RHS")
m.C = Param(m.b, doc="cost coefficients")
#variable
m.x = Var(m.b, within=NonNegativeReals)
def obj_rule(m):
return sum(m.C[t]*m.x[t] for t in m.b)
m.object_f = Objective(rule=obj_rule, sense=maximize, doc="Objective function")
def cons_rule(m,i):
return sum(m.A[i,j]*m.x[j] for j in m.b) <= m.B[i]
m.cons1 = Constraint(m.a, rule=cons_rule, doc="constraints")
data = DataPortal()
data.load(filename=str(path_model_in_set.joinpath('a.csv')), format='set', set='a')
data.load(filename=str(path_model_in_set.joinpath('b.csv')), format='set', set='b')
#the problem is in this line.
data. Load(filename=str(path_model_in_par.joinpath('Matrix_info.csv')), format='array', index=['A'], param=['1','2','3'])
data. Load(filename=str(path_model_in_par.joinpath('B.csv')), index=['a'], param=['B'])
data.load(filename=str(path_model_in_par.joinpath('C.csv')), index=['b'], param=['C'])
instance = m.create_instance(data)
print(instance.A)
optimizer = 'gurobi'
solver = SolverFactory(optimizer)
instance.write('LPP.lp', io_options={'symbolic_solver_labels': True})
solver_results = solver.solve(instance, tee=True)
solver_results.write()
instance.solutions.load_from(solver_results)
CSV files for matrix A is
A 1 2 3
1 2 1 1
2 1 2 1
3 0 0 1

Error in subscribing "/scan" topic, modify the messages and publish to the new topic

I would like to improve the LDS-01 sensor of the turtlebot3 by subscribing the message.ranges, modify the messange.ranges by applying some algorithm to the message and publish it to the new topic as shown below. But there are an error when I run the coding.
Before this, I have run the same coding as How to subscribe "/scan" topic, modify the messages and publish to the new topic? and there is no error to run this code. I think this is because the algorithm is only compute one by one of the message.ranges which is from 1; 2; 3; until 360 degree. It means that the matrix of the message.ranges is 360 x 1.
But for the coding below, the algorithm needs to compute five value at one times which is 1 2 3 4 5; 2 3 4 5 6; 3 4 5 6 7; until 360 1 2 3 4 degree again since lds-01 sensor is 360 degree. It means that the matrix of the message.ranges needs to change from 360 x 1 to 360 x 5. But there is an error when I run the coding below.
How to solve this problem and is there anyone can help with my coding? Thank you in advance!
#! /usr/bin/env python
import rospy
from sensor_msgs.msg import LaserScan
from numpy import *
import numpy as np
def callback(msg):
x1 = msg.ranges
x22 = np.array(x1,dtype=float)
x2 = matrix('x22 x22(2:360;1) x22(3:360;1:2) x22(4:360;1:3) x22(5:360;1:4)')
#input 1
x1_xoffset = matrix ('0;0;0;0;0')
x1_gain = matrix ('0.0307564548089385;0.0381097564300047;0.0308794477170062;0.0306353793381491;0.0324886282550904')
x1_ymin = -1
#layer 1
b1 = matrix ('-3.0022961030147494732;1.1284344283916103446;10.262689092808290781;-0.29108190341738160445;1.6910182135862883435;-1.4322186646812866684;0.52038673092297094147;0.18373415980376742174;-1.341864158161501841;8.9924977389929185989;-6.5122750450398561028;1.610769930183955978;-2.7072823580198375204;-3.071861929436806804;2.089532698983309178')
IW1_1 = matrix ('1.1763831014323093971 -0.022205589873535169082 1.3591906653400733784 0.35171992356252657075 -0.090715245174806585782;-0.33137985382807932933 0.7589349385846153595 -0.79263062237043191427 -3.0721179898719421786 -0.48109484027945054185;-2.0429705214887010634 -1.4215783235189332068 -2.2199535121273483718 5.6383715387809294484 9.3956079158810990037;-1.0582400260177218243 2.2756497752355073771 -1.4894441143471608413 -0.61366692742938355742 -1.7609538885010909137;0.32284523401768933093 -2.3716027653122901953 2.9198002838288754646 1.6727926692167303102 1.4016343126251111784;0.64284592426311937263 1.9670290884990859759 -0.8613791137489327232 -0.76088524923761946539 -0.5846670508779477915;-1.0662823986094978057 -0.38913892204807792874 -1.9927038658686935246 -0.89079948781370843491 -0.062953202997214421921;1.3836374075598649735 0.82293783803825726331 -1.0449519484800251501 2.2182027529674033239 1.9552752800894290797;2.1909981502076187887 -2.7456420582638014771 -1.0375844062452397321 -1.8757795009105702189 -0.76052914811528571359;5.0141311791138925003 3.8600626154505972565 3.7213564064231658968 3.1907998160592647707 -5.4753580388207421237;-7.3738127265306703251 0.81690452601147378608 -1.848533301150358632 1.4523073997719444517 -0.66541668998457348394;-0.41953258579903940362 -1.8045840188098498658 1.3538831558038899594 0.82232112784155764196 -0.036636531083722792546;-0.28307053443826624139 0.97238373514558673616 -0.44631585409406204779 1.395531629393004236 -0.91460564492552842708;-0.24800624331256537758 -0.12091709836330821748 0.57989534406924081456 1.2276541890871852658 -0.80248852007095816674;-0.027878630077996850029 -1.4092029396990795043 -1.5425528632120226735 -1.6945480178338363508 -0.066421346305691020273')
#layer 2
b2 = matrix ('-3.3718607680138723559')
LW2_1 = matrix ('1.1577237841084386805 3.1188616770417478818 11.377170228092280624 2.0941520852461419366 -5.8125506022667261519 1.8927565783053732495 2.1715202069861394563 -3.9047604811323477492 -2.558429670659956745 8.1105881568708060314 -7.0980360301043301519 -3.1203137130883740191 0.91759847912706682393 2.0087541762502567622 1.2751834061996529801')
# Output 1
y1_ymin = -1
y1_gain = 2.85714285714286
y1_xoffset = 0
#input 1
xp1 = ((x2 - x1_xoffset)*(x1_gain))+x1_ymin
#layer 1
n1 = IW1_1*xp1+b1
a1 = 2/(1+exp(-2*n1))-1
#layer 2
a2 = LW2_1*a1+b2
# Output 1
y1 = ((a2-y1_ymin)/(y1_gain))+y1_xoffset
y2 = y1.tolist()[0]
scan.header = msg.header
scan.angle_min = msg.angle_min
scan.angle_max = msg.angle_max
scan.angle_increment = msg.angle_increment
scan.time_increment = msg.time_increment
scan.scan_time = msg.scan_time
scan.range_min = msg.range_min
scan.range_max = msg.range_max
scan.ranges = y2
scan.intensities = msg.intensities
pub.publish(scan)
rospy.init_node("ann_realdata_publisher")
sub = rospy.Subscriber('/scan', LaserScan, callback)
pub = rospy.Publisher('/scan_realdata', LaserScan, queue_size=1)
rate = rospy.Rate(2)
scan = LaserScan()
rospy.spin()

Different results with matlab cumtrapz and scipy.integrate cumtrapz

Im translating some matlab code to python code and debugging both codes i get a different result from a call to the cumtrapz function, i also verified that the input data of both is similar. This are the codes:
Python Code
from numpy import zeros, ceil, array, mean, ptp, abs, sqrt, power
from scipy.integrate import cumtrapz
def step_length_vector(ics_y, fcs_y, acc_y, l, sf):
step_length_m1 = zeros(int(ceil(len(ics_y)/2))-1)
for i in range(0, len(ics_y)-2, 2):
av = acc_y[int(ics_y[i]):int(ics_y[i+2])+1]
t = array(range(1, int((ics_y[i+2]-ics_y[i])+2)))/sf
hvel = cumtrapz(t, av - mean(av), initial=0)
h = cumtrapz(t, hvel - mean(hvel), initial=0)
hend = ptp(h)
sl = 6.8*(sqrt(abs(2*l*hend - hend**2)))
step_length_m1[int(ceil(i/2))] = sl
return step_length_m1
Matlab Code
function [StepLengthM1] = StepLengthVector(ICsY,FCsY,ACCY,l,sf)
StepLengthM1 = zeros(1,ceil(length(ICsY)/2)-1);
for i= 1:2:length(ICsY)-2
av = ACCY(ICsY(i):ICsY(i+2));
t = (1:(ICsY(i+2)-ICsY(i))+1)/sf;
hvel = cumtrapz(t,av-mean(av));
h = cumtrapz(t,hvel-mean(hvel));
hend = peak2peak(h);
sl = 6.8*(sqrt(abs(2*l*hend - hend.^2)));
StepLengthM1(ceil(i/2)) = sl;
end
end
The hvel variable is different for both codes. Maybe im using wrong the scipy cumtrapz because i asume that the initial value that recives is 0. In both cases the inputs ics_y(ICsy), fcs_y(FCsY), acc_y(ACCY) are one dimensional arrays and l and sf are scalars.
Thanks!!!
(If this question is about cumtrapz, you should simplify your tests to just a single call to cumtrapz with the same input arrays in matlab and Python. Also, be sure you read the matlab and SciPy documentation of each function carefully. The SciPy functions are typically not exact duplicates of the corresponding matlab function.)
The problem is that when you give both x and y values, the order in which they are given in matlab/octave is x, y, but in the SciPy version, it is y, x.
For example,
octave:11> t = [0 1 1.5 4 4.5 6]
t =
0.00000 1.00000 1.50000 4.00000 4.50000 6.00000
octave:12> y = [1 2 3 -2 0 1]
y =
1 2 3 -2 0 1
octave:13> cumtrapz(t, y)
ans =
0.00000 1.50000 2.75000 4.00000 3.50000 4.25000
To get the same result with scipy.integrate.cumtrapz:
In [22]: from scipy.integrate import cumtrapz
In [23]: t = np.array([0, 1, 1.5, 4, 4.5, 6])
In [24]: y = np.array([1, 2, 3, -2, 0, 1])
In [25]: cumtrapz(y, t, initial=0)
Out[25]: array([0. , 1.5 , 2.75, 4. , 3.5 , 4.25])

How to append the first element of a matrix onto a list over a loop?

I have two loops that runs for a different x and y coordinates and for each different (x,y) coordinates, a linear equation is being solved for force 1 and force 2 using matrices method i.e. finding the inverse of A if Ax = C. For each loop it gives an answer as a matrix where first element is force 1 and 2nd element is force 2 at those specific coordinates. Here's my code:
import numpy as np
from scipy import linalg
def Force():
Force1 = np.zeros((160,90))
Force2 = np.zeros((160,90))
for x in np.arange(0,16.1,0.1):
for y in np.arange(1,9.1,0.1):
l1 = np.hypot(x,y)
l2 = np.hypot(15-x,y)
A = np.array([[(x/l1),((x-15)/l2)],[(y/l1),(y/l2)]])
c = np.array([[0],[70*9.81]])
F = linalg.solve(A,c)
Force1[x,y] = F[0]
Force2[x,y] = F[1]
print("Force 1 = {} \nForce 2 = {}\n".format(F[0], F[1]))
so at each point (x,y) a matrix [[Force 1],[Force 2]] is solved. Now I would like to append all the Force1(s) into a list of Force1[x,y] and similarly for Forces2(s) so that I can do
plt.imshow[Force1]
plt.imshow[Force2]
to plot a 2 heatmaps. How would I go about doing that?
This solves your issue - you were trying to assign to indices in Force1 and Force2 of type float. I've changed the for loops to use enumerate instead, and tweaked the assignment so it assigns F[0][0] and F[1][0].
import numpy as np
from scipy import linalg
def Force():
Force1 = np.zeros((160,90))
Force2 = np.zeros((160,90))
for i, x in enumerate(np.arange(0,16,0.1)):
for j, y in enumerate(np.arange(1,9,0.1)):
l1 = np.hypot(x,y)
l2 = np.hypot(15-x,y)
A = np.array([[(x/l1),((x-15)/l2)],[(y/l1),(y/l2)]])
c = np.array([[0],[70*9.81]])
F = linalg.solve(A,c)
Force1[i, j] = F[0][0]
Force2[i, j] = F[1][0]
# print("Force 1 = {} \nForce 2 = {}\n".format(F[0], F[1]))
plt.imshow(Force1)
plt.show()
plt.imshow(Force2)
plt.show()
Force()
The generated plots are:
and

Why norm of matrix is differ from norm of array in Python Numpy?

I am trying to use numpy to get norm of a vector. By using array or matrix, I got different results.
If a = np.array([3,4]), the result is correct: n1=7, n2= 5, ninf=4.
If a = np.matrix('3 4') the result is incorrect: n1=4, n2=5, ninf=7
Could anyone tell me what's wrong in following code? Thanks a lot.
import numpy as np
a = np.matrix('3 4')
n1 = np.linalg.norm(a,ord=1)
n2 = np.linalg.norm(a,ord=2)
ninf = np.linalg.norm(a,ord = np.inf)
print(repr(n1)) # should be 7
print(repr(n2)) # should be 5
print(repr(ninf)) # should be 4

Categories