title: lmfit: best way of adding several constrained parameters
body: <p>I'd like to describe some experimental data using a model which needs <em>n</em> different parameters, which are all mutually constrained according to:</p>
  <p>phi<sub>1</sub> + phi<sub>2</sub> + phi<sub>3</sub> + ... + phi<sub>n</sub> = 1</p>
  <p>with</p>
  <p>phi<sub>i+1</sub> &lt; phi<sub>i</sub></p>
  <p>and</p>
  <p>0 &lt; phi<sub>i </sub> &lt; 1</p>
  <p>Building on the suggestion of the lmfit manual on the use of constraints (<a href="https://lmfit.github.io/lmfit-py/constraints.html" rel="nofollow noreferrer">https://lmfit.github.io/lmfit-py/constraints.html</a>), I wrote the following piece of code:</p>
  <pre><code>fit_params = Parameters()
  for i in range(len(Files)):
          filename = Files[i]
          fit_params.add('z_knot0', value = 0.0, vary = False) #position of first knot
          fit_params.add('phi_knot0', value = guessed['phi_knot0'][filename], min=0.1, max=1.0, vary = True) #volume fraction of brush at the brush/substrate interface. 
          for j in range(1,GFP['n_knots']+1):
              fit_params.add('d_knot' + str(j), value = guessed['d_knot'+str(j)][filename], min = 1.0, max = 100.0, vary = True) #spacing between two consecutive knots
              ex = 'd_knot' + str(j) + ' + z_knot' + str(j-1)
              # print(ex)
              fit_params.add('z_knot' + str(j), expr=ex) #z position of jth knot.
      
              fit_params.add('delta_phi_knot' + str(j), value = guessed['delta_phi_knot'+str(j)][filename], min = 0.0, max = 0.5, vary = True) #decrease of polymer volume fraction between two consecutive knots
              ex1 = 'phi_knot' + str(j-1) + '- delta_phi_knot' + str(j) 
              phi_knot = ex1 + ' if ' + ex1 + ' &gt; 0 else 0'
              
              fit_params.add('phi_knot' + str(j), expr=phi_knot)
  </code></pre>
  <p>what worries me, is if this part of the code:</p>
  <pre><code>fit_params.add('delta_phi_knot' + str(j), value = guessed['delta_phi_knot'+str(j)][filename], min = 0.0, max = 0.5, vary = True) #decrease of polymer volume fraction between two consecutive knots
  ex1 = 'phi_knot' + str(j-1) + '- delta_phi_knot' + str(j) 
  phi_knot = ex1 + ' if ' + ex1 + ' &gt; 0 else 0'
  fit_params.add('phi_knot' + str(j), expr=phi_knot)
  </code></pre>
  <p>is an issue for the fitting routine (I use the differential evolution method). I am not getting any error, and the constraints seems also to be correctly taken into account when modelling the data. However, the fitting routine does not seem to converge towards a good solution, as I am able to simulate a curve which has a smaller chi^2 value than the one obtained from the fit. This seems to most delicate part of the code where something which I do not understand might take place.</p>
  <p>I am grateful for any advice. Thanks,
  Leonardo</p>