Least Squares¶
Reference¶
SAS/OR example: https://go.documentation.sas.com/?docsetId=ormpug&docsetTarget=ormpug_nlpsolver_gettingstarted05.htm&docsetVersion=15.1&locale=en
SAS/OR code for example: https://support.sas.com/documentation/onlinedoc/or/ex_code/151/nlpsg01.html
Model¶
import sasoptpy as so
import pandas as pd
def test(cas_conn, data=None):
# Use default data if not passed
if data is None:
data = pd.DataFrame([
[4, 8, 43.71],
[62, 5, 351.29],
[81, 62, 2878.91],
[85, 75, 3591.59],
[65, 54, 2058.71],
[96, 84, 4487.87],
[98, 29, 1773.52],
[36, 33, 767.57],
[30, 91, 1637.66],
[3, 59, 215.28],
[62, 57, 2067.42],
[11, 48, 394.11],
[66, 21, 932.84],
[68, 24, 1069.21],
[95, 30, 1770.78],
[34, 14, 368.51],
[86, 81, 3902.27],
[37, 49, 1115.67],
[46, 80, 2136.92],
[87, 72, 3537.84],
], columns=['x1', 'x2', 'y'])
m = so.Model(name='least_squares', session=cas_conn)
# Regression model: L(a,b,c) = a * x1 + b * x2 + c * x1 * x2
a = m.add_variable(name='a')
b = m.add_variable(name='b')
c = m.add_variable(name='c')
x1 = data['x1']
x2 = data['x2']
y = data['y']
err = m.add_implicit_variable((
y[i] - (a * x1[i] + b * x2[i] + c * x1[i] * x2[i]) for i in data.index
), name='error')
m.set_objective(so.expr_sum(err[i]**2 for i in data.index),
sense=so.MIN,
name='total_error')
m.solve(verbose=True, options={'with': 'nlp'})
return m.get_objective_value()
Output¶
In [1]: import os
In [2]: hostname = os.getenv('CASHOST')
In [3]: port = os.getenv('CASPORT')
In [4]: from swat import CAS
In [5]: cas_conn = CAS(hostname, port)
In [6]: import sasoptpy
In [7]: from examples.client_side.least_squares import test
In [8]: test(cas_conn)
NOTE: Initialized model least_squares.
NOTE: Added action set 'optimization'.
NOTE: Converting model least_squares to OPTMODEL.
var a;
var b;
var c;
impvar error_0 = - 4 * a - 8 * b - 32 * c + 43.71;
impvar error_1 = - 62 * a - 5 * b - 310 * c + 351.29;
impvar error_2 = - 81 * a - 62 * b - 5022 * c + 2878.91;
impvar error_3 = - 85 * a - 75 * b - 6375 * c + 3591.59;
impvar error_4 = - 65 * a - 54 * b - 3510 * c + 2058.71;
impvar error_5 = - 96 * a - 84 * b - 8064 * c + 4487.87;
impvar error_6 = - 98 * a - 29 * b - 2842 * c + 1773.52;
impvar error_7 = - 36 * a - 33 * b - 1188 * c + 767.57;
impvar error_8 = - 30 * a - 91 * b - 2730 * c + 1637.66;
impvar error_9 = - 3 * a - 59 * b - 177 * c + 215.28;
impvar error_10 = - 62 * a - 57 * b - 3534 * c + 2067.42;
impvar error_11 = - 11 * a - 48 * b - 528 * c + 394.11;
impvar error_12 = - 66 * a - 21 * b - 1386 * c + 932.84;
impvar error_13 = - 68 * a - 24 * b - 1632 * c + 1069.21;
impvar error_14 = - 95 * a - 30 * b - 2850 * c + 1770.78;
impvar error_15 = - 34 * a - 14 * b - 476 * c + 368.51;
impvar error_16 = - 86 * a - 81 * b - 6966 * c + 3902.27;
impvar error_17 = - 37 * a - 49 * b - 1813 * c + 1115.67;
impvar error_18 = - 46 * a - 80 * b - 3680 * c + 2136.92;
impvar error_19 = - 87 * a - 72 * b - 6264 * c + 3537.84;
min total_error = (- 4 * a - 8 * b - 32 * c + 43.71) ^ (2) + (- 62 * a - 5 * b - 310 * c + 351.29) ^ (2) + (- 81 * a - 62 * b - 5022 * c + 2878.91) ^ (2) + (- 85 * a - 75 * b - 6375 * c + 3591.59) ^ (2) + (- 65 * a - 54 * b - 3510 * c + 2058.71) ^ (2) + (- 96 * a - 84 * b - 8064 * c + 4487.87) ^ (2) + (- 98 * a - 29 * b - 2842 * c + 1773.52) ^ (2) + (- 36 * a - 33 * b - 1188 * c + 767.57) ^ (2) + (- 30 * a - 91 * b - 2730 * c + 1637.66) ^ (2) + (- 3 * a - 59 * b - 177 * c + 215.28) ^ (2) + (- 62 * a - 57 * b - 3534 * c + 2067.42) ^ (2) + (- 11 * a - 48 * b - 528 * c + 394.11) ^ (2) + (- 66 * a - 21 * b - 1386 * c + 932.84) ^ (2) + (- 68 * a - 24 * b - 1632 * c + 1069.21) ^ (2) + (- 95 * a - 30 * b - 2850 * c + 1770.78) ^ (2) + (- 34 * a - 14 * b - 476 * c + 368.51) ^ (2) + (- 86 * a - 81 * b - 6966 * c + 3902.27) ^ (2) + (- 37 * a - 49 * b - 1813 * c + 1115.67) ^ (2) + (- 46 * a - 80 * b - 3680 * c + 2136.92) ^ (2) + (- 87 * a - 72 * b - 6264 * c + 3537.84) ^ (2);
solve with nlp / ;
create data solution from [i]= {1.._NVAR_} var=_VAR_.name value=_VAR_ lb=_VAR_.lb ub=_VAR_.ub rc=_VAR_.rc;
create data dual from [j] = {1.._NCON_} con=_CON_.name value=_CON_.body dual=_CON_.dual;
NOTE: Submitting OPTMODEL code to CAS server.
NOTE: Problem generation will use 8 threads.
NOTE: The problem has 3 variables (3 free, 0 fixed).
NOTE: The problem has 0 linear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The OPTMODEL presolver removed 0 variables, 0 linear constraints, and 0 nonlinear constraints.
NOTE: Using analytic derivatives for objective.
NOTE: The NLP solver is called.
NOTE: The Interior Point Direct algorithm is used.
Objective Optimality
Iter Value Infeasibility Error
0 95424613 0 3.48646173
1 7.18629678 0 0.0000000055789
NOTE: Optimal.
NOTE: Objective = 7.1862967833.
NOTE: The output table 'SOLUTION' in caslib 'CASUSER(casuser)' has 3 rows and 6 columns.
NOTE: The output table 'DUAL' in caslib 'CASUSER(casuser)' has 0 rows and 4 columns.
NOTE: The CAS table 'solutionSummary' in caslib 'CASUSER(casuser)' has 12 rows and 4 columns.
NOTE: The CAS table 'problemSummary' in caslib 'CASUSER(casuser)' has 12 rows and 4 columns.
Out[8]: 7.186296783293