everyone
Is it possible to solve the following like:
x = np.matrix([[8.3,-20.6],[-20.6,65.8]])
y is a function of P:
y = lambda P: np.matrix([[0.02P,-0.02P], [-0.02P,0.04P]])
I want to find the P value given conditions that:
P>0, det(x-y)==0;
Is there any handy way for this?
Thank you very much!
Shawn
If you don't mind using an additional package, scipy.optimize has a number of methods that would be perfect. Otherwise, you could implement your own zero finding function.
If you want to go the scipy route:
1) Define your problem as a function that takes your unknown parameter (P) as its first argument, and returns the value you want to minimize:
def zerofn(P, x, y):
return np.linalg.det(x - y(P))
2) Optimize this function, using scipy. The example here uses a simple Newton-Raphson zero finder, but there are many other options which you might want to use to specify parameter bounds (e.g. P > 0).
import scipy.optimize as opt
opt.newton(zerofn, x0=1, args=(x, y))
>> 160.25865914054651
The result of this zero finder is your optimized value of P.
Related
I am very new to programming, and had to use sympy for a school project.
I think I get that using nonlinsolve to return an angle gives an ImageSet with the angle + 2n*pi. However I want it to return only the value of the angle (in the interval [0,pi/2]), and as one value and not an interval.
from sympy import nonlinsolve, symbols,cos
x=symbols('x')
print(nonlinsolve([cos(x)-1],[x]).args[0][0])
I want the result to be 0 and not 2*n*pi.
Clarification : I know that the result is correct, but I only want one value, that I can use algebraically, and I don't know how Sympy works (how to manipulate ImageSets)
So I might be wrong because i dont use sympy, but the solution that solvers return seems to be corect to me.
ImageSet(Lambda(_n, 2*_n*pi), Integers)
From what I understand solver returned lambda function. Cosinus is a cyclic function which means it reapeats it's value every 2PI. So the solver says first solution (_n = 0) is 0, second (_n = 1) is 2pi and so on.
look at the function plot and it will hopefully make sense:
Wolfram Alpha - (cos(x) - 1)
EDIT: I think you need to use intersect method of imageset like this( note that intersect returns all the intersections, here i selected just the first one):
from sympy import nonlinsolve, symbols,cos, Interval
import math
x = symbols('x')
f = nonlinsolve([cos(x)-1], [x]).args[0][0]
sol = f.intersect(Interval(0, math.pi/2)).args[0]
print(sol)
I'm a beginner with Python (v 3.7) and I am trying to evaluate numerically a derivative of a symbolic function that contains parameters but I can't feed the values in a successful way.
I've tried different combinations getting inspiration from reading this question and something also from here.
Here is a minimal example that replicates my problem:
import sympy as sym
from sympy import*
x, y, a = sym.var('x, y, a')
def f(x,y):
return a*x**2 + x*y**2
fprime = sym.diff(f(x,y),x)
print(f(1,1))
print(fprime.evalf(subs={x: 1, y: 1}))
As expected the output of the first print is a+1 but the issue arrives with the second print because the output I get is 2.0*a*x + y**2 while I wish to obtain 2*a+1.
How shall I amend my code? I've also tried defining fprime separately and run the following:
def fprime(x,y):
return sym.diff(f(x,y),x)
print(fprime(x,1))
but still I can't make any progress. Thanks!
Just use substitution. Use evalf when you are trying to get a number from an expression that is a number. Your, containing unevaluated a is not yet a number so evaluation rejects it.
>>> fprime.subs({x: 1, y: 1})
2*a + 1
my task is to integrate the following equation for 1d Fresnel diffraction, in red in:
The point is that you are fourier transforming the aperture to a pattern on the screen, but for now just focussing on integrating the horizontal strip in 1d (ignoring the height for now). yprime is thus ignored. You also have fixed z and k, and j is an imaginary number. I have written the following code for it:
import math
import numpy as np
import cmath
k=5
z=5
x=0
j=cmath.sqrt(-1)
func=math.exp((j*k/2*z)(x-xp)*(x-xp))
def X(xp1,xp2,function,N):
h=(xp2-xp1)/N
y=0.0
xp=xp1
for x in np.arange(1, N/2 +1): #summing odd order y terms
y+=4*f(xp)
xp+=2*h
xp=xp1+2*h
for x in np.arange(0, N/2): #summing even order y terms
y+=2*f(x)
xp+=2*h
integral= (h/3)*(y+f(xp1)+f(xp2))
return integral
print(simpson(0,5,func,10))
however, it is saying that xp is not defined. but I clearly have defined xp in the function.
Does anyone have an idea what could be wrong?
Thanks
EDIT: here is a neater version of my code. But it's still asking me to define xp..
import math
import cmath
lamda=0.2
k=(2*math.pi)/lamda
z=0.1
def expfunc(x, xp):
func = math.exp(((1j)*k/2*z)(x-(xp))*(x-(xp)))
return(func)
def X(xp1,xp2,x,f,N):
h=(xp2-xp1)/N
y=0.0
xp=xp1
for i in np.arange(1, N/2 +1): #summing odd order y terms
y+=4*f(xp)
xp+=2*h
xp=xp1+2*h
for i in np.arange(0, N/2): #summing even order y terms
y+=2*f(xp)
xp+=2*h
integral= (h/3)*(y+f(xp1)+f(xp2))
return integral
print(X(0,1,x,expfunc,10))
You try to use the variable xp before you have defined it.
import math
import numpy as np
import cmath
k=5
z=5
x=0
j=cmath.sqrt(-1)
func=math.exp((j*k/2*z)(x-xp)*(x-xp)) #xp is not defined yet
You gave initial values for everything else except xp.
when you define func as you did
func=math.exp((j*k/2*z)(x-xp)*(x-xp))
you define a single value called func. What you probably want is something like that:
func = lambda x,xp : math.exp((j*k/2*z)(x-xp)*(x-xp))
and then change call of func to
y+=4*f(x, xp)
and
y+=2*f(x, xp)
I believe the issue is y+=4*f(xp) inside the first for loop of the function X.
At the very end you have print(X(0,1,x,expfunc,10)) where expfunc is acting as f in the bit of code y+=4*f(xp). The function expfunc takes two arguments, one of them defined as xp. Although the variable you pass in f is defined with the name xp, the function only sees that you have passed in the first argument x and not the argument xp.
Further, I do not see the variable x in print(X(0,1,x,expfunc,10)) defined anywhere.
Also, the second snipit of code is much different than the first. If the same questions apply then you should remove the first snipit altogether and/or rephrase your questions because from what I see in the second chuck the error you claim to be getting should not be raised.
Scipy offers many useful tools for root finding, notably fsolve. Typically a program has the following form:
def eqn(x, a, b):
return x + 2*a - b**2
fsolve(eqn, x0=0.5, args = (a,b))
and will find a root for eqn(x) = 0 given some arguments a and b.
However, what if I have a problem where I want to solve for the a variable, giving the function arguments in x and b? Of course, I could recast the initial equation as
def eqn(a, x, b)
but this seems long winded and inefficient. Instead, is there a way I can simply set fsolve (or another root finding algorithm) to allow me to choose which variable I want to solve for?
You can go with your first idea in a more concise way using lambda functions:
fsolve(lambda a,x,b: eqn(x, a, b), x0=0.5, args=(x,b))
That is, rearrange the arguments in the lambda wrapper so you don't have to write a separate def eqn2(a,x,b).
I need to write a function that can write and solve the inverse of tan for values that I input as two arrays. Sometimes the array on the denominator contains zero so always a division by zero occurs. I don't know how to get rid of the error and make the answer return pi/2 instead.
def deviation(x):
if capture(x)==True:
for i in range(len(yvf)):
theta=sp.arctan(xvf/yvf) #xvf and yvf are two arrays
First of all: write xvf[i] and yvf[i] to access the single elements of the arrays one after the other.
Secondly discern if yvf[i] equals zero or not:
if yvf[i] == 0:
theta = math.pi/2.0
else:
theta = sp.arctan(xvf[i]/yvf[i])
If you import numpy, I suggest using arctan2 instead of arctan (see this doc). This function manages zero values in the 2nd argument.
If not, you can solve this problem with atan2 function of math library and zip built-in function :
import math
xvf = [0.,2.,2.]
yvf = [20.,0.,2.]
def arctan(xvf,yvf):
return [math.atan2(x,y) for x,y in zip(xvf,yvf)]
print arctan(xvf,yvf)