I am attempting to write a program that reads two sets data from a .csv file into arrays, and then fits it to a piecewise function. What's most important to me is that these fits are done simultaneously because they have the same parameters. This piecewise function is my attempt to do so, though if you know a better way to fit them simultaneously I'd also greatly appreciate advice regarding that.
To avoid having to upload the csv files I've added the data directly into the arrays.
import numpy
import csv
import matplotlib
from scipy import optimize
xdata = [2.0, 10.0, 30.0, 50.0, 70.0, 90.0, 110.0, 130.0, 150.0, 250.0, 400.0, 1002.0, 1010.0, 1030.0, 1050.0, 1070.0, 1090.0, 1110.0, 1130.0, 1150.0, 1250.0, 1400.0]
ydata = [0.013833958803215633, 0.024273268442992078, 0.08792766000711709, 0.23477725658012044, 0.31997367288103884, 0.3822895295625711, 0.46037063893452784, 0.5531831477605121, 0.559757863748663, 0.6443036770720387, 0.7344601382896991, 2.6773979205076136e-09, 9.297289736857164e-10, 0.10915332214935693, 0.1345307163724643, 0.1230161681870127, 0.11286094974672768, 0.09186485171688986, 0.06609131137369342, 0.052616358869021135, 0.034629686697483314, 0.03993853791147095]
The first 11 points I want to fit to the function labeled 'SSdecay', and the second 11 points I want to fit to the function labeled 'SUdecay'. My attempt at doing this simultaneously was making the piecewise function labeled 'fitfunciton'.
#defines functions to be used in fitting
#to fit the first half of data
def SSdecay(x, lam1, lam2, norm, xoff):
return norm*(1 + lam2/(lam1 - lam2)*numpy.exp(-lam1*(x - xoff)) -
lam1/(lam1 - lam2)*numpy.exp(-lam2*(x - xoff)))
#to fit the second half of data
def SUdecay(x, lam1, lam2, norm, xoff):
return norm*(lam1/(lam1 - lam2))*(-numpy.exp(-lam1*(x - xoff)) +
numpy.exp(-lam2*(x - xoff)))
#piecewise function combining SS and SU functions to fit the whole data set
def fitfunction(x, lam1, lam2, norm, xoff):
y = numpy.piecewise(x,[x < 1000, x >= 1000],[SSdecay(x, lam1, lam2, norm, xoff),SUdecay(x, lam1, lam2, norm, xoff)])
return y
#fits the piecewise function with initial guesses for parameters
p0=[0.01,0.02,1,0]
popt, pcov = optimize.curve_fit(fitfunction, xdata, ydata, p0)
print(popt)
print(pcov)
After running this I get the error:
ValueError: NumPy boolean array indexing assignment cannot assign 22 input values to the 11 output values where the mask is true
It seems as though curve_fit does not like that I'm using a piecewise function but I am unsure why or if it is a fixable kind of problem.