|
3 | 3 | #include <cplex.h>
|
4 | 4 | //#include <algorithm>
|
5 | 5 |
|
| 6 | +// todo(aykut) |
| 7 | +// error check routine. Copied from OsiCpxSolverInterface. |
| 8 | +// I am not sure whether this is a license violation. This |
| 9 | +// may be removed/replaced in future. |
| 10 | +// I would not experince any problem if this function was not static |
| 11 | +// in OsiCpxSolverInterface.cpp. Since it is, I have to copy it here |
| 12 | +// and create redundancy. |
| 13 | +static inline void |
| 14 | +checkCPXerror(int err, std::string cpxfuncname, std::string osimethod) { |
| 15 | + if(err != 0) { |
| 16 | + char s[100]; |
| 17 | + sprintf( s, "%s returned error %d", cpxfuncname.c_str(), err ); |
| 18 | +#ifdef DEBUG |
| 19 | + std::cerr << "ERROR: " << s << " (" << osimethod << " in OsiCpxSolverInterface)" << std::endl; |
| 20 | +#endif |
| 21 | + throw CoinError(s, osimethod.c_str(), "OsiCplexSolverInterface"); |
| 22 | + } |
| 23 | +} |
| 24 | + |
| 25 | + |
6 | 26 | // default constructor
|
7 | 27 | OsiCplexSolverInterface::OsiCplexSolverInterface(): OsiCpxSolverInterface() {
|
8 | 28 | CPXENVptr env = getEnvironmentPtr();
|
@@ -117,29 +137,53 @@ void OsiCplexSolverInterface::getConicConstraint(int index,
|
117 | 137 | void OsiCplexSolverInterface::addConicConstraint(OsiLorentzConeType type,
|
118 | 138 | int numMembers,
|
119 | 139 | const int * members) {
|
120 |
| - if (type==OSI_RQUAD) { |
121 |
| - std::cerr << "Rotated Cones are not implemented yet!" << std::endl; |
122 |
| - throw std::exception(); |
123 |
| - } |
124 | 140 | int status;
|
125 | 141 | CPXLPptr lp = getMutableLpPtr();
|
126 | 142 | CPXENVptr env = getEnvironmentPtr();
|
127 |
| - double * qval = new double[numMembers]; |
128 |
| - qval[0] = -1.0; |
129 |
| - std::fill_n(qval+1, numMembers-1, 1.0); |
130 |
| - status = CPXaddqconstr (env, lp, 0, numMembers, |
131 |
| - 0.0, 'L', NULL, NULL, |
132 |
| - members, members, qval, NULL); |
133 |
| - if (status != 0) { |
134 |
| - std::cerr << "Cplex function is not successful." << std::endl; |
135 |
| - throw std::exception(); |
| 143 | + if (type==OSI_QUAD) { |
| 144 | + double * qval = new double[numMembers]; |
| 145 | + qval[0] = -1.0; |
| 146 | + std::fill_n(qval+1, numMembers-1, 1.0); |
| 147 | + status = CPXaddqconstr (env, lp, 0, numMembers, |
| 148 | + 0.0, 'L', NULL, NULL, |
| 149 | + members, members, qval, NULL); |
| 150 | + delete[] qval; |
| 151 | + checkCPXerror(status, std::string("CPXaddqconstr"), |
| 152 | + std::string("addConicConstraint")); |
| 153 | + // leading variable is nonnegative |
| 154 | + double bound[] = {0.0}; |
| 155 | + char lu[] = {'L'}; |
| 156 | + status = CPXchgbds (env, lp, 1, members, lu, bound); |
| 157 | + checkCPXerror(status, std::string("CPXchgbds"), |
| 158 | + std::string("addConicConstraint")); |
136 | 159 | }
|
137 |
| - // leading variable is nonnegative |
138 |
| - double bound[] = {0.0}; |
139 |
| - char lu[] = {'L'}; |
140 |
| - status = CPXchgbds (env, lp, 1, members, lu, bound); |
141 |
| - if (status != 0) { |
142 |
| - std::cerr << "Cplex function is not successful." << std::endl; |
| 160 | + else if (type==OSI_RQUAD) { |
| 161 | + double * qval = new double[numMembers-1]; |
| 162 | + qval[0] = -2.0; |
| 163 | + std::fill_n(qval+1, numMembers-1, 1.0); |
| 164 | + int * members2 = new int[numMembers-1]; |
| 165 | + members2[0] = members[0]; |
| 166 | + std::copy(members+2, members+numMembers, members2+1); |
| 167 | + status = CPXaddqconstr (env, lp, 0, numMembers-1, |
| 168 | + 0.0, 'L', NULL, NULL, |
| 169 | + members+1, members2, qval, NULL); |
| 170 | + delete[] qval; |
| 171 | + delete[] members2; |
| 172 | + checkCPXerror(status, std::string("CPXaddqconstr"), |
| 173 | + std::string("addConicConstraint")); |
| 174 | + // leading variable is nonnegative |
| 175 | + double bound[] = {0.0}; |
| 176 | + char lu[] = {'L'}; |
| 177 | + // update lower bound to 0 for leading variables |
| 178 | + status = CPXchgbds (env, lp, 1, members, lu, bound); |
| 179 | + checkCPXerror(status, std::string("CPXchgbds"), |
| 180 | + std::string("addConicConstraint")); |
| 181 | + status = CPXchgbds (env, lp, 1, members+1, lu, bound); |
| 182 | + checkCPXerror(status, std::string("CPXchgbds"), |
| 183 | + std::string("addConicConstraint")); |
| 184 | + } |
| 185 | + else { |
| 186 | + std::cerr << "Unknown cone type!" << std::endl; |
143 | 187 | throw std::exception();
|
144 | 188 | }
|
145 | 189 | }
|
|
0 commit comments