Simaltaneous trignometric equation in python - python-3.x

My task is to simulate a 3 DOF robotic arm system in python. The aim is to trace out a 3D Gaussian surface. Input data is coordinates of the end effector gained using 3D Gaussian equation. The code is supposed to solve a system of the trigonometric equation to find out angles theta1, theta2 & theta3. I used "solve([eqn1,eqn2,eqn3],theta1,theta2,theta3)" to solve for the system of equation. Python is taking a too long time to respond.
I tried solving using fsolve, but the results were incomparable to the solution from MATLAB. Btw, I got a very good simulation in MATLAB using "solve".
I am using Python 3.7.3 through spyder under Anaconda 2019.03 environment in Windows 10.
Generating data set (Gaussian surface) : P matrix
a = 8
x0 = 0
y0 = 0
sigmax = 3
sigmay = 3
P_x = np.arange(7,-8,-1)
P_y = np.arange(7,-8,-1)
xx , yy = np.meshgrid(P_x,P_y)
s_x,s_y = np.subtract(xx,x0),np.subtract(yy,y0)
sq_x,sq_y = np.square(s_x),np.square(s_y)
X,Y = np.divide(sq_x,2*(sigmax**2)),np.divide(sq_y,2*(sigmay**2))
E = np.exp(-X-Y)
zz = np.multiply(E,a)
xx,yy,zz = xx.flatten(),yy.flatten(),zz.flatten()
P = np.vstack([yy,xx,zz]).T
import numpy as np
from sympy import *
from sympy import Symbol, solve, Eq
for j in range(len(P)):
theta1 = Symbol('theta1',real = True)
theta2 = Symbol('theta2',real = True)
theta3 = Symbol('theta3',real = True)
x,y,z = P[j,0],P[j,1],P[j,2]
eq1 = Eq(R1*cos(theta1) + R2*cos(theta1)*cos(theta2) +
R3*cos(theta1)*cos(theta3) - x)
eq2 = Eq(R1*sin(theta1) + R2*cos(theta2)*sin(theta1) +
R3*cos(theta3)*sin(theta1) - y)
eq3 = Eq(R2*sin(theta2) + R3*sin(theta3) -z )
solve([eq1,eq2,eq3],theta1,theta2,theta3)
solution[j,0] = degrees(theta1)
solution[j,1] = degrees(theta3)
solution[j,2] = degrees(theta2)
Expected result: Solution matrix with values of theta1, theta2 & theta3.
Python takes too much time to respond.

Related

It keeps saying "ReferenceError: Can't find variable: math"

So I'm supposed to write a Python program that creates 3 circles of spheres: one on the xy plane, one in the yz plane, and one in the xz plane. Each ring should be centered on the origin, and I'm trying to use three while loops to do this, but nothing is working in VPython and I don't know why.
Web VPython 3.2
from visual import *
x = math.radians(360)
n = m = l = 0
while n <= x:
sphere(pos = vector(math.sin(n), math.cos(m), 1), radius = 0.1, color = color.red)
n = n + (math.radians(30))
m = m + (math.radians(30))
n = m = l = 0
while n <= x:
sphere(post = vector(math.sin(n), m, math.cos(1)), radius = 0.1, color = color.blue)
n = n + (math.radians(30))
l = l + (math.radians(30))
n = m = l = 0
while m <= x:
sphere(pos = vector(n, math.sin(m), math.cos(1)), radius = 0.1, color = color.green)
m = m + (math.radians(30))
l = l + (math.radians(30))
Are you using Web VPython (webvpython.org or equivalently glowscript.org) or the vpython module available for use with installed Python (see installation info at vpython.org)? In either case, simply delete all occurrences of "math."; the math library is available without this (and its use with Web VPython gives an error). Also note that the name of the Python module is "vpython", not "visual".

Optimizing asymmetrically reweighted penalized least squares smoothing (from matlab to python)

I'm trying to apply the method for baselinining vibrational spectra, which is announced as an improvement over asymmetric and iterative re-weighted least-squares algorithms in the 2015 paper (doi:10.1039/c4an01061b), where the following matlab code was provided:
function z = baseline(y, lambda, ratio)
% Estimate baseline with arPLS in Matlab
N = length(y);
D = diff(speye(N), 2);
H = lambda*D'*D;
w = ones(N, 1);
while true
W = spdiags(w, 0, N, N);
% Cholesky decomposition
C = chol(W + H);
z = C \ (C' \ (w.*y) );
d = y - z;
% make d-, and get w^t with m and s
dn = d(d<0);
m = mean(d);
s = std(d);
wt = 1./ (1 + exp( 2* (d-(2*s-m))/s ) );
% check exit condition and backup
if norm(w-wt)/norm(w) < ratio, break; end
end
that I rewrote into python:
def baseline_arPLS(y, lam, ratio):
# Estimate baseline with arPLS
N = len(y)
k = [numpy.ones(N), -2*numpy.ones(N-1), numpy.ones(N-2)]
offset = [0, 1, 2]
D = diags(k, offset).toarray()
H = lam * numpy.matmul(D.T, D)
w_ = numpy.ones(N)
while True:
W = spdiags(w_, 0, N, N, format='csr')
# Cholesky decomposition
C = cholesky(W + H)
z_ = spsolve(C.T, w_ * y)
z = spsolve(C, z_)
d = y - z
# make d- and get w^t with m and s
dn = d[d<0]
m = numpy.mean(dn)
s = numpy.std(dn)
wt = 1. / (1 + numpy.exp(2 * (d - (2*s-m)) / s))
# check exit condition and backup
norm_wt, norm_w = norm(w_-wt), norm(w_)
if (norm_wt / norm_w) < ratio:
break
w_ = wt
return(z)
Except for the input vector y the method requires parameters lam and ratio and it runs ok for values lam<1.e+07 and ratio>1.e-01, but outputs poor results. When values are changed outside this range, for example lam=1e+07, ratio=1e-02 the CPU starts heating up and job never finishes (I interrupted it after 1min). Also in both cases the following warning shows up:
/usr/local/lib/python3.9/site-packages/scipy/sparse/linalg/dsolve/linsolve.py: 144: SparseEfficencyWarning: spsolve requires A to be CSC or CSR matrix format warn('spsolve requires A to be CSC or CSR format',
although I added the recommended format='csr' option to the spdiags call.
And here's some synthetic data (similar to one in the paper) for testing purposes. The noise was added along with a 3rd degree polynomial baseline The method works well for parameters bl_1 and fails to converge for bl_2:
import numpy
from matplotlib import pyplot
from scipy.sparse import spdiags, diags, identity
from scipy.sparse.linalg import spsolve
from numpy.linalg import cholesky, norm
import sys
x = numpy.arange(0, 1000)
noise = numpy.random.uniform(low=0, high = 10, size=len(x))
poly_3rd_degree = numpy.poly1d([1.2e-06, -1.23e-03, .36, -4.e-04])
poly_baseline = poly_3rd_degree(x)
y = 100 * numpy.exp(-((x-300)/15)**2)+\
200 * numpy.exp(-((x-750)/30)**2)+ \
100 * numpy.exp(-((x-800)/15)**2) + noise + poly_baseline
bl_1 = baseline_arPLS(y, 1e+07, 1e-01)
bl_2 = baseline_arPLS(y, 1e+07, 1e-02)
pyplot.figure(1)
pyplot.plot(x, y, 'C0')
pyplot.plot(x, poly_baseline, 'C1')
pyplot.plot(x, bl_1, 'k')
pyplot.show()
sys.exit(0)
All this is telling me that I'm doing something very non-optimal in my python implementation. Since I'm not knowledgeable enough about the intricacies of scipy computations I'm kindly asking for suggestions on how to achieve convergence in this calculations.
(I encountered an issue in running the "straight" matlab version of the code because the line D = diff(speye(N), 2); truncates the last two rows of the matrix, creating dimension mismatch later in the function. Following the description of matrix D's appearance I substituted this line by directly creating a tridiagonal matrix using the diags function.)
Guided by the comment #hpaulj made, and suspecting that the loop exit wasn't coded properly, I re-visited the paper and found out that the authors actually implemented an exit condition that was not featured in their matlab script. Changing the while loop condition provides an exit for any set of parameters; my understanding is that algorithm is not guaranteed to converge in all cases, which is why this condition is necessary but was omitted by error. Here's the edited version of my python code:
def baseline_arPLS(y, lam, ratio):
# Estimate baseline with arPLS
N = len(y)
k = [numpy.ones(N), -2*numpy.ones(N-1), numpy.ones(N-2)]
offset = [0, 1, 2]
D = diags(k, offset).toarray()
H = lam * numpy.matmul(D.T, D)
w_ = numpy.ones(N)
i = 0
N_iterations = 100
while i < N_iterations:
W = spdiags(w_, 0, N, N, format='csr')
# Cholesky decomposition
C = cholesky(W + H)
z_ = spsolve(C.T, w_ * y)
z = spsolve(C, z_)
d = y - z
# make d- and get w^t with m and s
dn = d[d<0]
m = numpy.mean(dn)
s = numpy.std(dn)
wt = 1. / (1 + numpy.exp(2 * (d - (2*s-m)) / s))
# check exit condition and backup
norm_wt, norm_w = norm(w_-wt), norm(w_)
if (norm_wt / norm_w) < ratio:
break
w_ = wt
i += 1
return(z)

A more efficient way of comparing two images in a python

I have a task where i need to specify the upper left coordinate of the smaller image in the larger image.
I implemented this code, however it is too slow since I have a time limit of 20 seconds, and in some datasets I have 3000 images. How can this be implemented more effectively? I can use numpy, scipy and all packages from the standard python library.
import numpy as np
from PIL import Image
map_image_path = input()
map_image = Image.open(map_image_path)
map_ar = np.asarray(map_image)
map_ar_y, map_ar_x = map_ar.shape[:2]
i = int(input())
dimensions = input()
patches=list()
for k in range(i):
patch_image_path = input()
patches.append(Image.open(patch_image_path))
for j in range(i):
patch_ar = np.asarray(patches[j])
patch_ar_y, patch_ar_x = patch_ar.shape[:2]
stop_x = map_ar_x - patch_ar_x + 1
stop_y = map_ar_y - patch_ar_y + 1
for x in range(0, stop_x):
for y in range(0, stop_y):
x2 = x + patch_ar_x
y2 = y + patch_ar_y
picture = map_ar[y:y2, x:x2]
if np.array_equal(picture, patch_ar):
print(str(x) + "," + str(y))

Errors when trying to solve large system of PDEs

I have a system of 18 linear (i'm assuming) PDEs. Howe ever they are very awkwardly shaped PDEs. Every time I try to use FiPy to solve the system of coupled PDEs I get an error. I have fixed most of them on my own but I can't seem to get past this one.
First you will need a list of equations that will be added later in the program:
import time
from fipy import Variable, FaceVariable, CellVariable, Grid1D, Grid2D, ExplicitDiffusionTerm, TransientTerm, DiffusionTerm, Viewer,PowerLawConvectionTerm, ImplicitSourceTerm
from fipy.tools import numerix
import math
import numpy as np
import sympy as sp
Temperature = 500.0 #Temperature in Celsius
Temp_K = Temperature + 273.15 #Temperature in Kelvin
Ea = [342,7,42,45,34] #Activation energy in order from the list excel/word file
#Frequency factor ko (Initial k)
k_0 =[5.9 * (10**15), 1.3 * (10**13), 1.0 * (10**12), 5.0 * (10**11), 1.2 * (10**13)]
fk1 = [math.exp((-1.0 * x)/(R*Temp_K)) for x in Ea] #Determines k value at given temperature value (exp(-Ea/R*T))
final_k = [fk1*k_0 for fk1,k_0 in zip(fk1,k_0)] #Multiplys by the inital k value to determine the k value at the given temperature (ko * exp(-Ea/R*T))
final_kcm = [x for x in final_k]
def rhs(eq):
eq_list = [-1.0*final_kcm[0]*EDC - final_kcm[1]*EDC*R1 - final_kcm[2]*EDC*R2 - final_kcm[3]*EDC*R4 - final_kcm[4]*EDC*R5 - final_kcm[5]*EDC*R6,
final_kcm[2]*EDC*R2 - final_kcm[8]*EC*R1 + final_kcm[13]*VCM*R2,
final_kcm[1]*EDC*R1 + final_kcm[6]*R2*R1 + final_kcm[7]*R1*R3 + final_kcm[8]*R1*EC + final_kcm[9]*R1*C11 + final_kcm[10]*R1*C112 + final_kcm[12]*R1*VCM + 2.0*final_kcm[20]*R1*C2H2,
2.0*final_kcm[20]*R2*C2H2,
final_kcm[15]*R5*VCM,
return eq_list[eq]
Here is the rest of the program I use to generate the system of PDEs.
EDC = CellVariable(mesh=mesh, hasOld=True, value=10)
EC = CellVariable(mesh=mesh, hasOld=True, value=0)
HCl = CellVariable(mesh=mesh, hasOld=True, value=0)
Coke = CellVariable(mesh=mesh, hasOld=True, value=0)
CP = CellVariable(mesh=mesh, hasOld=True, value=0)
EDC.constrain(10, mesh.facesLeft)
EC.constrain(0., mesh.facesLeft)
HCl.constrain(0., mesh.facesLeft)
Coke.constrain(0., mesh.facesLeft)
CP.constrain(0., mesh.facesLeft)
nsp =18
u_x = [[ [0,]*nsp for n in range(nsp) ]]
for z in range(nsp):
u_x[0][z][z] = 1.0
eq0 = TransientTerm(var = EDC) == PowerLawConvectionTerm(coeff = u_x, var = EDC) + ImplicitSourceTerm(rhs(0),var = EDC)
eq1 = TransientTerm(var = EC) == PowerLawConvectionTerm(coeff = u_x, var = EC) + ImplicitSourceTerm(rhs(1),var = (EC))
eq2 = TransientTerm(var = HCl) == PowerLawConvectionTerm(coeff = u_x, var = HCl) + ImplicitSourceTerm(rhs(2),var = (HCl))
eq3 = TransientTerm(var = Coke) == PowerLawConvectionTerm(coeff = u_x, var = Coke) + ImplicitSourceTerm(rhs(3),var = (Coke))
eq4 = TransientTerm(var = CP) == PowerLawConvectionTerm(coeff = u_x, var = CP) + ImplicitSourceTerm(rhs(4),var = (CP))
eqn = eq0 & eq1 & eq2 & eq3 & eq4
if __name__ == '__main__':
viewer = Viewer(vars = (EDC,EC,HCl,Coke,CP))
viewer.plot()
for t in range(1):
EDC.updateOld()
EC.updateOld()
HCl.updateOld()
Coke.updateOld()
CP.updateOld()
eqn.solve(dt=1.e-3)
Sorry for the long code but I can't really show it any other way. Anyway this is the error it returns :
File
"C:\Users\tjcze\Anaconda3\lib\site-packages\fipy\matrices\scipyMatrix.py",
line 218, in addAt
assert(len(id1) == len(id2) == len(vector))
AssertionError
What should I do to get this system to work correctly?
The error is because of whatever you're trying to do with u_x. u_x should be a rank-1 FaceVariable.
Its shape should be #dims x #faces (or #dims x 1); it should not be (#eqns x #eqns).
Setting u_x = [1.] gets rid of the AssertionError.
You will then get a series of warnings:
UserWarning: sweep() or solve() are likely to produce erroneous results when `var` does not contain floats.
Fix this by initializing all of your CellVariables with floats, e.g.,
EDC = CellVariable(mesh=mesh, hasOld=True, value=10.)
instead of
EDC = CellVariable(mesh=mesh, hasOld=True, value=10)
With those changes, the code runs. It doesn't do anything interesting, but that's hardly surprising, as it's way too complicated at this stage. 18 equations only obfuscates things. I strongly recommend you troubleshoot this problem with <= 2 equations.
At this point, your equations aren't coupled at all (eq0 only implicitly depends on EDC, eq1 only on EC, etc.). This isn't wrong, but not terribly useful. Certainly no point in the eq = eq0 & eq1 & ... syntax. EDC is the only variable with a chance of evolving, and it's constant, so it won't evolve, either.
In future, please provide examples that actually run (up to the point of the error, anyway).

ValueError: operands could not be broadcast together with shapes (3,) (0,)

My aim is to make the image1 move along the ring from its current position upto 180 degree. I have been trying to do different things but nothing seem to work. My final aim is to move both the images along the ring in different directions and finally merge them to and make them disappear.I keep getting the error above.Can you please help? Also can you tell how I can go about this problem?
from visual import *
import numpy as np
x = 3
y = 0
z = 0
i = pi/3
c = 0.120239 # A.U/minute
r = 1
for theta in arange(0, 2*pi, 0.1): #range of theta values; 0 to
xunit = r * sin(theta)*cos(i) +x
yunit = r * sin(theta)*sin(i) +y
zunit = r*cos(theta) +z
ring = curve( color = color.white ) #creates a curve
for theta in arange(0, 2*pi, 0.01):
ring.append( pos=(sin(theta)*cos(i) +x,sin(theta)*sin(i) +y,cos(theta) +z) )
image1=sphere(pos=(2.5,-0.866,0),radius=0.02, color=color.yellow)
image2=sphere(pos=(2.5,-0.866,0),radius=0.02, color=color.yellow)
earth=sphere(pos=(-3,0,-0.4),color=color.yellow, radius =0.3,material=materials.earth) #creates the observer
d_c_p = pow((x-xunit)**2 + (y-yunit)**2 + (z-zunit)**2,0.5) #calculates the distance between the center and points on ring
d_n_p = abs(yunit + 0.4998112152755791) #calculates the distance to the nearest point
t1 = ( d_c_p+d_n_p)/c
t0=d_c_p/c
t=t1-t0 #calculates the time it takes from one point to another
theta = []
t = []
dtheta = np.diff(theta) #calculates the difference in theta
dt = np.diff(t) #calculates the difference in t
speed = r*dtheta/dt #hence this calculates the speed
deltat = 0.005
t2=0
while True:
rate(5)
image2.pos = image2.pos + speed*deltat #increments the position of the image1
t2 = t2 + deltat
Your problem is that image2.pos is a vector (that's the "3" in the error message) but speed*deltat is a scalar (that's the "0" in the error message). You can't add a vector and a scalar. Instead of a scalar "speed" you need a vector velocity. There seem to be some errors in indentation in the program you posted, so there is some possibility I've misinterpreted what you're trying to do.
For VPython questions it's better to post to the VPython forum, where there are many more VPython users who will see your question than if you post to stackoverflow:
https://groups.google.com/forum/?fromgroups&hl=en#!forum/vpython-users

Resources