Defining a function to call within axScatter.plt - python

I'm currently working on defining a mathematical function, i.e.,
from numpy import tanh
def stravinska(Z, eps=0.5):
return ((-0.86928)+(0.052481*Z))*(tanh(((2.66503)-(4.44255*Z))))-1.251617
SII = np.linspace(-3.0, 0.20)
To call within
axScatter_middle.plot(SII, stravinska(Z=0.5), '-k')
However, the following error is return upon compilation:
ValueError: x and y must have same first dimension
I'm scratching my head as to where I have gone wrong as I have used this method successfully many times before. What does this error mean and how can I rectify this problem?
I'm essentially trying to plot the equation 10 from this paper: Semi-empirical analysis of Sloan Digital Sky Survey galaxies – III. How to distinguish AGN hosts

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from numpy import tanh
def stravinska(log_SII_Ha, eps=0):
strav = ((-30.787)+(1.1358*(log_SII_Ha))+(0.27297*((log_SII_Ha)**2)))*(tanh(5.7409* (log_SII_Ha)))-31.093
return strav
SII = np.linspace(-3.0, 0.20)
axScatter_middle.plot(SII, stravinska(SII), '-k')

Related

Create 3D graph from 2 variable function that uses linear algebra to solve system of equations

So, i'm doing this project for my electromagnetism class and I need to plot a 3D graph in python. I normally plot 3d graphs using meshgrids, but the function used to calculate the value uses linear algebra, and since meshgrids are matrices, it seems to be causing some problems. Does anyone know how to work around this problem?
This is the code I made:
#Vamos importar os módulos que precisamos
from math import *
from cmath import *
from numpy import linalg
import numpy as np
import matplotlib.pyplot as plt
import math
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
from numpy import exp,arange
k=0.1
R1=0.4*3.5
R2=R1
L1=83e-6
L2=L1
C1=0.47e-6
C2=C1
Rc=10
M=k*sqrt(L1*L2)
V1=5
# the function that I'm going to plot
def CalcularTransformador(K,w):
Vp=2/pi*5
Rc=10
XL1=1j*w*L1
XL2=1j*w*L2
XC1=(-1j)/(w*C1)
XC2=(-1j)/(w*C2)
M=K*sqrt(L1*L2)
XM=1j*w*M
Z=np.array([[R1+XL1+XC1, -XM],[-XM, XL2+R2+(Rc*XC2)/(Rc+XC2)]])
V=np.array([Vp,0])
i=np.dot(linalg.inv(Z),V)
V2=i[1]*(XL2+R2+(Rc*XC2)/(Rc+XC2))
return i[0], i[1],V2
CalcularTransformador(0.1,150000)
w_angular=np.linspace(150000,260000,1000)
k=np.linspace(0,1,1000)
K,W = meshgrid(k, w_angular)
#print(K,W)
Valores = CalcularTransformador(K, W)
im = imshow(Valores,cmap=cm.RdBu)
show()

python: Plotting and optimizing the same function

Lets say I have the following function:
def f(x):
return log(3*exp(3*x) + 7*exp(7*x))
I want to do two things:
1) plot the function over a range of x-values
2) find the root of the function using the Newton method from scipy
My problem is that it seems that plotting is best done with a numpy array x=np.linspace(-2,2,1000), but then evaluating the function results in erros TypeError: only size-1 arrays can be converted to Python scalars. I can fix this by simply changing log and exp to np.log and np.exp, respectively.
But doing so then makes scipy.optimize.newton unhappy.
It seems like I need to define the function twice, once for use in plotting (with np. ...) and once for optimizing in the form given above.
I can't imagine that this is actually the case. Any hints would be greatly appreciated.
Seems legit, you just need to use numpy functions instead of base math functions:
import numpy as np
from scipy import optimize
import matplotlib.pyplot as plt
%matplotlib inline
def f(x):
return np.log(3*np.exp(3*x) + 7*np.exp(7*x))
x = np.linspace(-2,2,1000)
y = f(x)
plt.scatter(x, y)
optimize.root(f, 1)

Minuit gives invalid log curve?

Trying to fit some data with to a log curve however my output is not valid and I don't understand what is causing the error. It's weird since this is what minuit is supose to do and it's a simple example so I don't get what the issue is.
from iminuit import Minuit
from math import pi
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def logis(x,a,b): #function to fit
return (1+x*np.log(x/b))*a
xlat=np.array([81.96100485, 64.96427609, 38.15520137, 45.75992993,
27.38344029, 23.41742996, 18.73586921, 18.07486749,
9.20589292, 4.83878931, 72.17070899, 71.08083681,
39.57647386, 31.63373626]) #xdata
lo=logis(xlat,92,30) #ydata
p=np.concatenate((np.array([92,30]),xlat,lo),axis=0) #all parameters
def chi(pa): #chisquare
chis=sum((92-pa[0:1])**2)+sum((30-pa[1:2])**2)+sum((xlat-pa[2:16])**2)+sum((lo-logis(pa[2:16],92,30))**2)
return chis
#minuit part
m = Minuit.from_array_func(chi,p,errordef=1)
fmin,para=m.migrad()
print(m.values)
print(fmin)
xn=[]
xtra=np.sort(xlat)
for i in range(2,16):
xn.append(m.values[i])
xr=np.array(xn)
#plot part
xp=np.linspace(min(xr),max(xr),14)
plt.figure(figsize=(14,8.5))
plt.plot(xp,logis(xp,m.values[0],m.values[1]))
plt.show

How code an integration formula using Python

I have an integration equations to calculate key rate and need to convert it into Python.
The equation to calculate key rate is given by:
where R(n) is:
and p(n)dn is:
The key rate should be plotted like this:
I have sucessfully plotted the static model of the graph using following equation:
import numpy as np
import math
from math import pi,e,log
import matplotlib.pyplot as plt
n1=np.arange(10, 55, 1)
n=10**(-n1/10)
Y0=1*(10**-5)
nd=0.25
ed=0.03
nsys=nd*n
QBER=((1/2*Y0)+(ed*nsys))/(Y0+nsys)
H2=-QBER*np.log2(QBER)-(1-QBER)*np.log2(1-QBER)
Rsp=np.log10((Y0+nsys)*(1-(2*H2)))
print (Rsp)
plt.plot(n1,Rsp)
plt.xlabel('Loss (dB)')
plt.ylabel('log10(Rate)')
plt.show()
However, I failed to plot the R^ratewise model. This is my code:
import numpy as np
import matplotlib.pyplot as plt
def h2(x):
return -x*np.log2(x)-(1-x)*np.log2(1-x)
e0=0.5
ed=0.03
Y0=1e-5
nd=0.25
nt=np.linspace(0.1,0.00001,1000)
y=np.zeros(np.size(nt))
Rate=np.zeros(np.size(nt))
eta_0=0.0015
for (i,eta) in enumerate(nt):
nsys=eta*nd
sigma=0.9
y[i]=1/(eta*sigma*np.sqrt(2*np.pi))*np.exp(-(np.log(eta/eta_0)+(1/2*sigma*sigma))**2/(2*sigma*sigma))
Rate[i]=(max(0.0,(Y0+nsys)*(1-2*h2(min(0.5,(e0*Y0+ed*nsys)/(Y0+nsys))))))*y[i]
plt.plot(nt,np.log10(Rate))
plt.xlabel('eta')
plt.ylabel('Rate')
plt.show()
Hopefully that anyone can help me to code the key rate with integration p(n)dn as stated above. This is the paper for referrence:
key rate
Thank you.
I copied & ran your second code block as-is, and it generated a plot. Is that what you wanted?
Using y as the p(n) in the equation, and the Rsp as the R(n), you should be able to use
NumPy's trapz function
to approximate the integral from the sampled p(n) and R(n):
n = np.linspace(0, 1, no_of_samples)
# ...generate y & Rst from n...
R_rate = np.trapz(y * Rst, n)
However, you'll have to change your code to sample y & Rst using the same n, spanning from 0 to 1`.
P.S. there's no need for the loop in your second code block; it can be condensed by removing the i's, swapping eta for nt, and using NumPy's minimum and maximum functions, like so:
nsys=nt*nd
sigma=0.9
y=1/(nt*sigma*np.sqrt(2*np.pi))*np.exp(-(np.log(nt/eta_0)+(1/2*sigma*sigma))**2/(2*sigma*sigma))
Rate=(np.maximum(0.0,(Y0+nsys)*(1-2*h2(np.minimum(0.5,(e0*Y0+ed*nsys)/(Y0+nsys))))))*y

Improper input: N=3 must not exceed M=1 (error trying to fit a gaussian function)

I'm pretty new to python and curve fitting and currently I'm trying to fit the graph below with a Gaussian
I'm following this tutorial and my code looks like this
import numpy as np
import matplotlib.pyplot as plt
from pylab import genfromtxt
from matplotlib import pyplot
from numpy import sqrt, pi, exp, linspace,loadtxt
from lmfit import Model
def gaussian(x,amp,cen,wid):
"1-d gaussian: gaussian(x,amp,cen,wid)"
return (amp/(sqrt(2*pi)*wid))*exp(-(x-cen)**2/(2*wid**2))
filelist=[]
time=[0.00,-1.33,-2.67,-4.00,-5.33,-6.67,1.13,2.67,4.00,5.33,6.67]
index=0
offset=0
filelist.append('0.asc')
for i in range(1,6):
filelist.append("-%s00.asc" %(i))
for i in range(1,6):
filelist.append("+%s00.asc" %(i))
sfgpeaks=[]
for fname in filelist:
data=np.genfromtxt(fname,delimiter=',',unpack=True,skip_footer=20)
SFGX=data[0,500:530]
SFGY=data[1,500:530]
SFGpeakY=np.max(SFGY)
sfgpeaks.append(SFGpeakY)
gmodel = Model(gaussian)
result = gmodel.fit(SFGpeakY, x=time[index], amp=5,cen=5,wid=3)
plt.plot(time[index],sfgpeaks[index],'ro')
plt.plot(time[index],result.init_fit, 'k--',label="Gaussian Fit")
plt.xticks(time)
index=index+1
print(pump2SHGX)
pyplot.title("Time Delay-SFG peak")
plt.xlabel("Timedelay[ps]")
plt.ylabel("Counts[arb.unit]")
plt.savefig("796and804nmtimesfg")
plt.legend(bbox_to_anchor=(1.0,0.5))
plt.show()
However, I'm getting an error when I try to add the data that I have(time delay and the Y value of the graph above) into the gaussian parameters.
The error I'm getting is this
TypeError: Improper input: N=3 must not exceed M=1
Does this error because I'm trying to insert a value from an array into the parameter??
Any help is much appreciated.
You have
result = gmodel.fit(SFGpeakY, x=time[index], amp=5,cen=5,wid=3)
which is passing 1 value as x and 1 value as the data. The model is then evaluated at that 1 point. The error message is the fit is complaining that you have 3 variables and 1 value.
You probably want to fit the data array SFGY with x set to SFGX,
result = gmodel.fit(SFGY, x=SFGX, amp=5,cen=5,wid=3)
though it wasn't clear to me what data is used in the plot you attached.
Also: you probably want to give initial values for amp, cen, and wid based on the data. Your SFGpeakY is probably a decent guess for amp, and SFGX.mean() and SFGX.std() are probably decent guesses or cen and wid.
Also: you plot result.init_fit labeled as "Gaussian Fit". result.init_fit will be the model evaluated with the initial values for the parameters. The best fit with the refined parameters will be in result.best_fit.

Categories

Resources