0

I’ve been trying to fit some parameters to a curve but I need to put a constraint on one of the constants and I don’t know how to make my code acknowledge the constraints and fit a value with the correct value. I’ll try to write a simple example code just to show my problem:

def chi(paras):
    mpi=paras[0:32]
    cf=paras[32]
    chif=0
    for i in range(32):
        chif+=((fpi-f(mpi,cf))/error)**2
    return chif
m=Minuit.from_array_func(chi,parin,parstep,name=parname,errordef=1)

fmin,param=m.migrad(ncall=10000)

print(m.values)

I want for example cf<=np.log(mpi**2). I’ve tried for example:

if cf<=np.log(mpi**2):
    chif+=((fpi-f(mpi,cf))/error)**2

else:
    pass

but it hasn’t worked. Is there anyway to put this constraint in the code?

Linus
  • 147
  • 4
  • 15
  • Well, for a very simple (but probably not best) solution, you could add `chif += np.inf` instead of the `pass` statement. That way, the result will be infinite, which is always larger than any valid attempt, and minuit should exclude that direction of its search. – 9769953 Mar 28 '19 at 13:37
  • What are you trying to loop over. You do not make use of `i`, so are you sure about this loop? – mikuszefski Apr 01 '19 at 09:08

1 Answers1

0

To this type of constrains there are always simple parameter transform solution. In this case you may define:

def chi( paras ):
    mpi = paras[ 0 : 32 ]
    s = paras[ 32 ]
    a = np.log( np.sum( np.array( mpi )**2 ) )
    cf = a - np.exp( -s )
    chif = 0
    for i in range( 32 ):
        chif += ( ( fpi - f( mpi, cf ) ) / error )**2
    return chif

The parameter s is allowed to vary from-np.inf to np.inf while the internal cf can vary from-np.inf to a = np.log( sum ( mpi**2 ) ). To get cf and its error you make standard error propagation.

mikuszefski
  • 3,943
  • 1
  • 25
  • 38