Skip to content

Commit 9cd62b4

Browse files
author
Benjamin Chrétien
committed
Add constraint scaling support
1 parent 00b680c commit 9cd62b4

File tree

3 files changed

+58
-6
lines changed

3 files changed

+58
-6
lines changed

src/roboptim/core/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ def argumentScaling(self):
316316
def argumentScaling(self, value):
317317
setArgumentScaling (self._problem, value)
318318

319-
def addConstraint (self, constraint, bounds):
320-
addConstraint (self._problem, constraint._function, bounds)
319+
def addConstraint (self, constraint, bounds, scaling = None):
320+
addConstraint (self._problem, constraint._function, bounds, scaling)
321321
self._constraints.append (constraint)
322322

323323
@property

src/wrap.cc

+49-3
Original file line numberDiff line numberDiff line change
@@ -1862,12 +1862,13 @@ addConstraint (PyObject*, PyObject* args)
18621862
problem_t* problem = 0;
18631863
Function* function = 0;
18641864
PyObject* py_bounds = 0;
1865+
PyObject* py_scaling = 0;
18651866

18661867
if (!PyArg_ParseTuple
1867-
(args, "O&O&O",
1868+
(args, "O&O&OO",
18681869
&detail::problemConverter, &problem,
18691870
&detail::functionConverter, &function,
1870-
&py_bounds))
1871+
&py_bounds, &py_scaling))
18711872
return 0;
18721873

18731874
if (!problem)
@@ -1929,9 +1930,32 @@ addConstraint (PyObject*, PyObject* args)
19291930
return 0;
19301931
}
19311932

1933+
double scaling = 1.;
1934+
if (py_scaling != Py_None)
1935+
{
1936+
if (PyFloat_Check (py_scaling))
1937+
{
1938+
scaling = PyFloat_AsDouble (py_scaling);
1939+
}
1940+
else if (PyList_Check (py_scaling)
1941+
&& (PyList_Size (py_scaling) == 1)
1942+
&& (PyFloat_Check (PyList_GetItem (py_scaling, 0))))
1943+
{
1944+
PyObject* tmp = PyList_GetItem (py_scaling, 0);
1945+
scaling = PyFloat_AsDouble (tmp);
1946+
}
1947+
else
1948+
{
1949+
PyErr_SetString (PyExc_TypeError,
1950+
"scaling should be a float or a list of floats.");
1951+
return 0;
1952+
}
1953+
}
1954+
19321955
problem->addConstraint (constraint,
19331956
Function::makeInterval (PyFloat_AsDouble (py_min),
1934-
PyFloat_AsDouble (py_max)));
1957+
PyFloat_AsDouble (py_max)),
1958+
scaling);
19351959
}
19361960
// Bounds = vector of pairs
19371961
else if (is_np_array
@@ -1944,6 +1968,28 @@ addConstraint (PyObject*, PyObject* args)
19441968
scaling_t scaling (constraint->outputSize (), 1.);
19451969
intervals_t bounds (constraint->outputSize ());
19461970

1971+
if (py_scaling != Py_None)
1972+
{
1973+
if (PyList_Check (py_scaling)
1974+
&& (PyList_Size (py_scaling) == constraint->outputSize ()))
1975+
{
1976+
for (int i = 0; i < constraint->outputSize (); ++i)
1977+
{
1978+
PyObject* tmp = PyList_GetItem (py_scaling, i);
1979+
if (PyFloat_Check (tmp))
1980+
{
1981+
scaling[i] = PyFloat_AsDouble (tmp);
1982+
}
1983+
}
1984+
}
1985+
else
1986+
{
1987+
PyErr_SetString (PyExc_TypeError,
1988+
"scaling should be a list of floats.");
1989+
return 0;
1990+
}
1991+
}
1992+
19471993
for (Function::size_type i = 0; i < constraint->outputSize (); ++i)
19481994
{
19491995
// TODO: check array type

tests/function.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,13 @@ def test_solver(self):
168168
g2 = DoubleSquare ()
169169
problem.addConstraint (g2, numpy.array ([[-1., 10.],[2., 3.]]))
170170

171-
self.assertEqual (problem.constraints, [g1, g2])
171+
g3 = Square ()
172+
problem.addConstraint (g3, [-1., 10.,], 0.1)
173+
174+
g4 = DoubleSquare ()
175+
problem.addConstraint (g4, numpy.array ([[-1., 10.],[2., 3.]]), [0.1, 0.2])
176+
177+
self.assertEqual (problem.constraints, [g1, g2, g3, g4])
172178

173179
solver = roboptim.core.PySolver ("ipopt", problem)
174180
print (solver)

0 commit comments

Comments
 (0)