def fit_monotonic_third_order(
        dfile_db,
        dcon_db=None,
        pred=None,
        target_mos=None,
        target_ci=None, 
        mapping=None):
    '''
    Fits third-order function with the constrained to be monotonically.
    increasing. This function may not return an optimal fitting.
    '''        
    y = dfile_db[target_mos].to_numpy()
    
    y_hat = dfile_db[pred].to_numpy()
    
    if dcon_db is None:
        if target_ci in dfile_db:
            ci = dfile_db[target_ci].to_numpy()   
        else:
            ci = 0        
    else:
        y_con = dcon_db[target_mos].to_numpy()
        
        if target_ci in dcon_db:
            ci = dcon_db[target_ci].to_numpy()   
        else:
            ci = 0         
                
    x = y_hat
    y_hat_min = min(y_hat) - 0.01
    y_hat_max = max(y_hat) + 0.01
 
    def polynomial(p, x):
        return p[0]+p[1]*x+p[2]*x**2+p[3]*x**3

    def constraint_2nd_der(p):
        return 2*p[2]+6*p[3]*x

    def constraint_1st_der(p):
        x = np.arange(y_hat_min, y_hat_max, 0.1)
        return p[1]+2*p[2]*x+3*p[3]*x**2

    def objective_con(p):
        x_map = polynomial(p, x)
        dfile_db['x_map'] = x_map
        x_map_con = dfile_db.groupby('con').mean().x_map.to_numpy() 
        err = x_map_con-y_con
        if mapping=='pError':
            p_err = (abs(err)-ci).clip(min=0)
            return (p_err**2).sum()
        elif mapping=='error':
            return (err**2).sum()
        else:
            raise NotImplementedError         

    def objective_file(p):
        x_map = polynomial(p, x)
        err = x_map-y
        if mapping=='pError':
            p_err = (abs(err)-ci).clip(min=0)
            return (p_err**2).sum()
        elif mapping=='error':
            return (err**2).sum()
        else:
            raise NotImplementedError 

    cons = dict(type='ineq', fun=constraint_1st_der)
    
    if dcon_db is None:
        res = minimize(
            objective_file,
            x0=np.array([0., 1., 0., 0.]),
            method='SLSQP', 
            constraints=cons,
            )
    else:
        res = minimize(
            objective_con,
            x0=np.array([0., 1., 0., 0.]),
            method='SLSQP', 
            constraints=cons,
            )
    b = res.x
    return b

    Fits third-order function with the constrained to be monotonically.
    increasing. This function may not return an optimal fitting.
    
speechscore/scores/nisqa/NISQA_lib.py