giaf / hpipm

High-performance interior-point-method QP and QCQP solvers
Other
552 stars 130 forks source link

solve error? #157

Open longjianquan opened 1 year ago

longjianquan commented 1 year ago

from numpy import array from qpsolvers import solve_qp

H=array([[1.,-1.],[-1.,2.]]) f=array([[-2.],[-6.]]).reshape((2,)) L=array([[-1.,2.],[1.,1.]]) k=array([[2.],[2.]]).reshape((2,))

x = solve_qp(H, f, L,k) print("QP solution: x = {}".format(x))

problem solve in python QP solution: x = [0.66666667 1.33333333]

hpipm

`#include

include

include

include

include

include

include

include

include

include

include

include

include

include <Eigen/Core>

int main() { double max_v =99999.0; // horizon lenght int N = 1; // number of input static int nnu[6] = {0, 0, 0, 0, 0, 0}; // number of states static int nnx[6] = {2, 0, 0, 0, 0, 0}; // number of input box constraints static int nnbu[6] = {0, 0, 0, 0, 0, 0}; // number of states box constraints static int nnbx[6] = {2, 0, 0, 0, 0, 0}; // number of general constraints static int nng[6] = {2, 0, 0, 0, 0, 0}; // number of softed constraints on state box constraints static int nnsbx[6] = {0, 0, 0, 0, 0, 0}; // number of softed constraints on input box constraints static int nnsbu[6] = {0, 0, 0, 0, 0, 0}; // number of softed constraints on general constraints static int nnsg[6] = {0, 0, 0, 0, 0, 0}; // number of input box constraints considered as equality static int nnbue[6] = {0, 0, 0, 0, 0, 0}; // number of states box constraints considered as equality static int nnbxe[6] = {0, 0, 0, 0, 0, 0}; // number of general constraints considered as equality static int nnge[6] = {0, 0, 0, 0, 0, 0};

// QP data

//
static double A[] = {0, 0, 0, 0};
//
static double B[] = {0, 0};
//
static double b[] = {0, 0};

//
static double Q[] = {1,-1,-1,2};
//
static double R[] = {0};
//
static double S[] = {0};
//
static double q[] = {-2,-6};
//
static double r[] = {0};

//
static double lbx0[] = {0.0,0.0};
//
static double ubx0[] = {max_v,max_v};
//
static int idxbx0[] = {0,1};

//
static double u_guess[] = {};
//
static double x_guess[] = {};
//
static double sl_guess[] = {};
//
static double su_guess[] = {};

// array of pointers

//
static double *AA[5] = {A, A, A, A, A};
//
static double *BB[5] = {B, B, B, B, B};
//
static double *bb[5] = {b, b, b, b, b};
//
static double *QQ[6] = {Q, Q, Q, Q, Q, Q};
//
static double *RR[6] = {R, R, R, R, R, R};
//
static double *SS[6] = {S, S, S, S, S, S};
//
static double *qq[6] = {q, q, q, q, q, q};
//
static double *rr[6] = {r, r, r, r, r, r};
//
static int *iidxbx[6] = {idxbx0, NULL, NULL, NULL, NULL, NULL};
//
static double *llbx[6] = {lbx0, NULL, NULL, NULL, NULL, NULL};
//
static double *uubx[6] = {ubx0, NULL, NULL, NULL, NULL, NULL};
//
static int *iidxbu[6] = {};
//
static double *llbu[6] = {};
//
static double *uubu[6] = {};
//
static double gh[4] = {-1,2,1,1};
static double gh1[] = {0};

static double *CC[6] = {gh, NULL, NULL, NULL, NULL, NULL};
//
static double *DD[6] = {gh1,gh1,gh1,gh1,gh1,gh1};
//
static double ghl[2] = {-max_v,-max_v};
static double ghl1[] = {-max_v,-max_v};
static double *llg[6] = {ghl, NULL, NULL, NULL, NULL, NULL};
//
static double ghu[2] = {2,2};
static double ghu1[] = {2,2};
static double *uug[6] = {ghu, NULL, NULL, NULL, NULL, NULL};
//
static double *ZZl[6] = {};
//
static double *ZZu[6] = {};
//
static double *zzl[6] = {};
//
static double *zzu[6] = {};
//
static int *iidxs[6] = {};
//
static double *llls[6] = {};
//
static double *llus[6] = {};
//
static int *iidxe[6] = {};

//
static double *uu_guess[6] = {};
//
static double *xx_guess[6] = {};
//
static double *ssl_guess[6] = {};
//
static double *ssu_guess[6] = {};

// export as global data

int *nu = nnu;
int *nx = nnx;
int *nbu = nnbu;
int *nbx = nnbx;
int *ng = nng;
int *nsbx = nnsbx;
int *nsbu = nnsbu;
int *nsg = nnsg;
int *nbue = nnbue;
int *nbxe = nnbxe;
int *nge = nnge;

double **hA = AA;
double **hB = BB;
double **hb = bb;
double **hQ = QQ;
double **hR = RR;
double **hS = SS;
double **hq = qq;
double **hr = rr;
int **hidxbx = iidxbx;
double **hlbx = llbx;
double **hubx = uubx;
int **hidxbu = iidxbu;
double **hlbu = llbu;
double **hubu = uubu;
double **hC = CC;
double **hD = DD;
double **hlg = llg;
double **hug = uug;
double **hZl = ZZl;
double **hZu = ZZu;
double **hzl = zzl;
double **hzu = zzu;
int **hidxs = iidxs;
double **hlls = llls;
double **hlus = llus;
int **hidxe = iidxe;

double **hu_guess = uu_guess;
double **hx_guess = xx_guess;
double **hsl_guess = ssl_guess;
double **hsu_guess = ssu_guess;

// arg
hpipm_mode mode = hpipm_mode::SPEED_ABS;
int iter_max = 30;
double alpha_min = 1e-8;
double mu0 = 1e4;
double tol_stat = 1e-4;
double tol_eq = 1e-5;
double tol_ineq = 1e-5;
double tol_comp = 1e-5;
double reg_prim = 1e-12;
int warm_start = 0;
int pred_corr = 1;
int ric_alg = 0;
int split_step = 1;
int ii, jj;

int hpipm_status;

int rep, nrep=10;

hpipm_timer timer;

/************************************************

// d_ocp_qp_dim_codegen("examples/c/data/test_d_ocp_data.c", "w", &dim);

/****

/****

}

`

result is x = 0.00069 1.99863

giaf commented 1 year ago

The issue is in the problem formulation and comes from the fact that HPIPM expects the matrices to be in column-major, so if you write static double gh[4] = {-1,2,1,1}; this is interpreted as the 2x2 matrix [ -1 1 | | 2 1 | that is the transposed of what you likely meant.

Then in general I would strongly suggest to use the dense QP formulation and solver in case of an unstructured QP, instead of using the OCP QP one that is tailored to quadratic programs with optimal control structure: this is both easier and more efficient.