Search code examples
pythonscipyscipy-optimizescipy-optimize-minimize

Solve factor with scipy minimize


I try to solve the factor x which multiply the sum of a vector 'Factor'. The sum of the vector 'Factor' should be the sum like the sum of the vector 'Basic'. First of all I read a csv which look like the following DataFrame:

enter image description here

Thanks for help in advance.

Well, I tried it with minimize and bounce too. Maybe it will be better to use scipy.optimize?

import pandas as pd
from scipy.optimize import minimize, optimize
import numpy as np

path='/scipytest.csv'

dffunc=pd.read_csv(path,  decimal=',', delimiter=';') 

BaseSum=np.sum(dffunc['Basic'])
FacSum=np.sum(dffunc['Factor'])

def f(x, FacSum):
    return BaseSum-FacSum*x


con = {'type': 'ineq',
       'fun': lambda BaseSum,FacSum: BaseSum-FacSum,
       'args': (FacSum,)}

x=0

result = minimize(f,(x,FacSum), args=(FacSum,), method='SLSQP', constraints=con)

print(result.x)
print(f(result.x))

raise ValueError("Objective function must return a scalar")

ValueError: Objective function must return a scalar


Solution

  • I don't think you necessarily need scipy.optimize.minimize. Since you are minimizing a scalar, you can use scipy.optimize.minimize_scalar (docs). This can be done like the following:

    from scipy.optimize import minimize_scalar
    import numpy as np
    
    
    # define vecs
    basic_vec  = np.array([123, 342, 235, 123,  56, 345, 234, 123, 345,  54, 234]).reshape(11, 1)
    factor_vec = np.array([234, 345, 453, 345, 456, 457,  23,  45,  56, 567,   5]).reshape(11, 1)
    # define sums
    BaseSum    = np.sum(basic_vec)
    FacSum     = np.sum(factor_vec)
    # define 
    f      = lambda x, FacSum: np.abs(BaseSum - FacSum * x)
    result = minimize_scalar(f, args   = (FacSum,), bounds = (0, FacSum), method = 'bounded')
    # prints
    print("x                    = ", result.x)
    print("BaseSum - FacSum * x = ", f(result.x, FacSum))
    

    Output:

    x                    =  0.741461642947231
    BaseSum - FacSum * x =  0.004465840431748802
    

    Moreover, I am not even sure why do you even need to use a minimization when you can simply do:

    x = BaseSum/FacSum