title: Piecewise function for least squares fit python
body: <p>I’m trying to extract 8 parameters from 3 measurements.
  For this to happen on 3 measures at the same time, I go through a part-by-part function.
  This technique works with optimize.curvefit but I can’t force the program to get a proper error on my settings. The conditions are too quickly met.</p>
  <p>So I now try to use leastsquare because I know I can adjust the gap that I want between my data and fitted'parameters with fscale.
  Unfortunately I get the following error message : &quot;NumPy boolean array indexing assignment cannot assign 29 input values to the 1 output values where the mask is true&quot; and I block in its resolution.</p>
  <p>Thanks for your help.</p>
  <pre><code>from scipy.optimize import least_squares
  import matplotlib.pyplot as plt
  import numpy as np
  
  l, t = [], []
  with open(&quot;Test.txt&quot;, &quot;r&quot;) as f_read:
      for line in f_read:
          line = line.strip()  #suppression du retour charriot en fin de ligne
          if line:
              ti, vi = [float(elt) for elt in line.split(&quot;\t&quot;)]  #conversion en nb
              l.append(ti), t.append(vi)
  
  for i in range(len(t)-7) :
      t[i]=(np.sin(t[i]/180*np.pi))**2
  
  t=np.array(t)
  l=np.array(l)
  
  
  def fun1(A,x,y):
      f=A[0]+A[1]/(x**2-A[2])-A[3]*x**2
      return f-y
  
  def fun2(A,x,y):
      f=A[4]+A[5]/(x**2-A[6])-A[7]*x**2
      return f-y
  
  def fun3(A,x,y):
      no=1/(A[0]+A[1]/(x**2-A[2])-A[3]*(x**2))
          
      ne=1/(A[4]+A[5]/(x**2-A[6])-A[7]*(x**2))
          
      no2=1/(A[0]+A[1]/((x/2)**2-A[2])-A[3]*((x/2)**2))
          
      f=(no2-no)/(ne-no)
      return f-y
  
  def fun4(A,x,y):    
      
      x=x-2
      l2=1.064
      l3=(1/x+1/l2)**(-1)
      no3=np.sqrt(A[0]+A[1]/(l3**2-A[2])-A[3]*(l3**2))
      no1=1/(A[0]+A[1]/(x**2-A[2])-A[3]*(x**2))
      ne1=1/(A[4]+A[5]/(x**2-A[6])-A[7]*(x**2))
      no2=1/(A[0]+A[1]/(l2**2-A[2])-A[3]*(l2**2))
      ne2=1/(A[4]+A[5]/(l2**2-A[6])-A[7]*(l2**2))
      
      X=(no1*(np.cos(y*180/np.pi))**2+ne1*(np.sin(y*180/np.pi))**2)**(-1/2)
      Y=(no2*(np.cos(y*180/np.pi))**2+ne2*(np.sin(y*180/np.pi))**2)**(-1/2)
      f=no3/l3-X/x-Y/l2
      return f
          
  
  A=2.84507614e+00
  B=1.37848818e-02
  C=3.68428479e-02
  D=2.43158022e-03
  E=2.88095276e+00
  F=3.12234625e-02
  G=2.40374019e-02
  H=3.88776226e-03
  p0 = np.array([A,B,C,D,E,F,G,H])
  
  def piecewise_linear(A,x,y):
      x0 = 0.7
      x1 = 1
      x2 = 3
      
      return np.piecewise(x, 
                          [x &lt; x0, 
                           (x &gt;= x0) &amp; (x &lt; x1),
                           (x &gt;= x1) &amp; (x &lt; x2),
                           x &gt;= x2], 
                          [lambda x: fun1(A,x,y), 
                           lambda x: fun2(A,x,y),
                           lambda x: fun3(A,x,y),
                           lambda x: fun4(A,x,y)])
    
  p = least_squares(piecewise_linear, p0, loss='soft_l1', f_scale=0.0001, args=(l, t)
                              , max_nfev=100000)
  print(p.x)
  </code></pre>