Skip to content

Commit a8f6e78

Browse files
authored
Deprecate the Lambda() and Sigma() functions for AugLagrangian (#439)
* Deprecate the Lambda() and Sigma() functions for AugLagrangian. * Add utility struct to differentiate between matrices and callbacks. * Update HISTORY. * Fix overload issues with LRSDP and new AugLagrangian types. * Fix some documentation to kick off another build. (I think there was an issue with dealgood.) * Remove spaces to kick the build off again.
1 parent 9fa90f1 commit a8f6e78

File tree

14 files changed

+276
-158
lines changed

14 files changed

+276
-158
lines changed

CONTRIBUTING.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ you have an improvement you would like to see, we would love to include it!
88

99
The ensmallen maintainer community overlaps heavily with the
1010
[mlpack](https://github.com/mlpack/mlpack) community, so development discussions
11-
can happen either here on Github, on the [mlpack mailing
12-
list](http://lists.mlpack.org/mailman/listinfo/mlpack), or in the #mlpack
13-
IRC channel on irc.freenode.net.
11+
can happen either here on Github or in the `#mlpack:matrix.org` channel on
12+
[Matrix](https://www.matrix.org/). See
13+
[here](https://www.mlpack.org/doc/developer/community.html) for more
14+
information.
1415

1516
Once a pull request is submitted, it must be reviewed and approved before a
1617
merge, to ensure that:

HISTORY.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,24 @@
4141
ActiveCMAES<FullSelection, BoundaryBoxConstraint> opt(lambda,
4242
BoundaryBoxConstraint(lowerBound, upperBound), ...);
4343
```
44-
4544
* Add proximal gradient optimizers for L1-constrained and other related
4645
problems: `FBS`, `FISTA`, and `FASTA`
4746
([#427](https://github.com/mlpack/ensmallen/pull/427)). See the
4847
documentation for more details.
4948

49+
* The `Lambda()` and `Sigma()` functions of the `AugLagrangian` optimizer,
50+
which could be used to retrieve the Lagrange multipliers and penalty
51+
parameter after optimization, are now deprecated
52+
([#439](https://github.com/mlpack/ensmallen/pull/439)). Instead, pass a
53+
vector and a double to the `Optimize()` function directly:
54+
55+
```c++
56+
augLag.Optimize(function, coordinates, lambda, sigma)
57+
```
58+
59+
and these will be filled with the final Lagrange multiplier estimates and
60+
penalty parameters.
61+
5062
### ensmallen 2.22.2: "E-Bike Excitement"
5163
###### 2025-04-30
5264
* Fix include statement in `tests/de_test.cpp`

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ Documentation and downloads: https://ensmallen.org
2222

2323
### Installation
2424

25-
ensmallen can be installed in several ways: either manually or via cmake,
25+
ensmallen can be installed in several ways: either manually or via cmake,
2626
with or without root access.
2727

28-
The cmake based installation will check the requirements
29-
and optionally build the tests. If cmake 3.3 (or a later version)
30-
is not already available on your system, it can be obtained
28+
The cmake based installation will check the requirements
29+
and optionally build the tests. If cmake 3.3 (or a later version)
30+
is not already available on your system, it can be obtained
3131
from [cmake.org](https://cmake.org).
3232

3333
Example cmake based installation with root access:
@@ -39,7 +39,7 @@ cmake ..
3939
sudo make install
4040
```
4141

42-
Example cmake based installation without root access,
42+
Example cmake based installation without root access,
4343
installing into `/home/blah/` (adapt as required):
4444

4545
```
@@ -49,7 +49,7 @@ cmake .. -DCMAKE_INSTALL_PREFIX:PATH=/home/blah/
4949
make install
5050
```
5151

52-
The above will create a directory named `/home/blah/include/`
52+
The above will create a directory named `/home/blah/include/`
5353
and place all ensmallen headers there.
5454

5555
To optionally build and run the tests
@@ -61,10 +61,10 @@ make ensmallen_tests
6161
./ensmallen_tests --durations yes
6262
```
6363

64-
Manual installation involves simply copying the `include/ensmallen.hpp` header
65-
***and*** the associated `include/ensmallen_bits` directory to a location
64+
Manual installation involves simply copying the `include/ensmallen.hpp` header
65+
***and*** the associated `include/ensmallen_bits` directory to a location
6666
such as `/usr/include/` which is searched by your C++ compiler.
67-
If you can't use `sudo` or don't have write access to `/usr/include/`,
67+
If you can't use `sudo` or don't have write access to `/usr/include/`,
6868
use a directory within your own home directory (eg. `/home/blah/include/`).
6969

7070

@@ -73,19 +73,19 @@ use a directory within your own home directory (eg. `/home/blah/include/`).
7373
If you have installed ensmallen in a standard location such as `/usr/include/`:
7474

7575
g++ prog.cpp -o prog -O2 -larmadillo
76-
77-
If you have installed ensmallen in a non-standard location,
78-
such as `/home/blah/include/`, you will need to make sure
79-
that your C++ compiler searches `/home/blah/include/`
80-
by explicitly specifying the directory as an argument/option.
76+
77+
If you have installed ensmallen in a non-standard location,
78+
such as `/home/blah/include/`, you will need to make sure
79+
that your C++ compiler searches `/home/blah/include/`
80+
by explicitly specifying the directory as an argument/option.
8181
For example, using the `-I` switch in gcc and clang:
8282

8383
g++ prog.cpp -o prog -O2 -I /home/blah/include/ -larmadillo
8484

8585

8686
### Example Optimization
8787

88-
See [`example.cpp`](example.cpp) for example usage of the L-BFGS optimizer
88+
See [`example.cpp`](example.cpp) for example usage of the L-BFGS optimizer
8989
in a linear regression setting.
9090

9191

@@ -103,8 +103,8 @@ Please cite the following paper if you use ensmallen in your research and/or
103103
software. Citations are useful for the continued development and maintenance of
104104
the library.
105105

106-
* Ryan R. Curtin, Marcus Edel, Rahul Ganesh Prabhu, Suryoday Basak, Zhihao Lou, Conrad Sanderson.
107-
[The ensmallen library for flexible numerical optimization](https://jmlr.org/papers/volume22/20-416/20-416.pdf).
106+
* Ryan R. Curtin, Marcus Edel, Rahul Ganesh Prabhu, Suryoday Basak, Zhihao Lou, Conrad Sanderson.
107+
[The ensmallen library for flexible numerical optimization](https://jmlr.org/papers/volume22/20-416/20-416.pdf).
108108
Journal of Machine Learning Research, Vol. 22, No. 166, 2021.
109109

110110
```

doc/optimizers.md

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -808,44 +808,20 @@ corresponding vector type (e.g. `arma::vec` or `coot::fvec`).
808808
The attributes of the optimizer may also be modified via the member methods
809809
`MaxIterations()`, `PenaltyThresholdFactor()`, `SigmaUpdateFactor()` and `LBFGS()`.
810810

811-
<details open>
812-
<summary>Click to collapse/expand example code.
813-
</summary>
811+
The `AugLagrangian` optimizer also allows manually specifying the initial
812+
Lagrange multipliers (`lambda`) and penalty parameter (`sigma`) directly in the
813+
call to `Optimize()`. For this, the following version of `Optimize()` should be
814+
used:
814815

815-
```c++
816-
/**
817-
* Optimize the function. The value '1' is used for the initial value of each
818-
* Lagrange multiplier. To set the Lagrange multipliers yourself, use the
819-
* other overload of Optimize().
820-
*
821-
* @tparam LagrangianFunctionType Function which can be optimized by this
822-
* class.
823-
* @param function The function to optimize.
824-
* @param coordinates Output matrix to store the optimized coordinates in.
825-
*/
826-
template<typename LagrangianFunctionType>
827-
bool Optimize(LagrangianFunctionType& function,
828-
arma::mat& coordinates);
816+
* `opt.Optimize(`_`function, coordinates, lambda, sigma, callbacks...`_`)`
829817

830-
/**
831-
* Optimize the function, giving initial estimates for the Lagrange
832-
* multipliers. The vector of Lagrange multipliers will be modified to
833-
* contain the Lagrange multipliers of the final solution (if one is found).
834-
*
835-
* @tparam LagrangianFunctionType Function which can be optimized by this
836-
* class.
837-
* @param function The function to optimize.
838-
* @param coordinates Output matrix to store the optimized coordinates in.
839-
* @param initLambda Vector of initial Lagrange multipliers. Should have
840-
* length equal to the number of constraints.
841-
* @param initSigma Initial penalty parameter.
842-
*/
843-
template<typename LagrangianFunctionType>
844-
bool Optimize(LagrangianFunctionType& function,
845-
arma::mat& coordinates,
846-
const arma::vec& initLambda,
847-
const double initSigma);
848-
```
818+
In that call, `lambda` should be a column vector of the same type as
819+
`coordinates`, and `sigma` is a `double`. `lambda` and `sigma` will be
820+
overwritten with the final values of the Lagrange multipliers and penalty
821+
parameters.
822+
823+
If `lambda` and `sigma` are not specified, then 0 is used as the initial value
824+
for all Lagrange multipliers and 10 is used as the initial penalty parameter.
849825

850826
</details>
851827

@@ -2400,6 +2376,20 @@ The attributes of the LRSDP optimizer may only be accessed via member methods.
24002376
| `size_t` | **`MaxIterations()`** | Maximum number of iterations before termination. | `1000` |
24012377
| `AugLagrangian` | **`AugLag()`** | The internally-held Augmented Lagrangian optimizer. | **n/a** |
24022378

2379+
Because `LRSDP` uses the [`AugLagrangian`](#auglagrangian) optimizer internally,
2380+
an additional overload of `Optimize()` is supplied to allow specifying the
2381+
initial Lagrange multiplier estimates and penalty parameter:
2382+
2383+
* `lrsdp.Optimize(`_`coordinates, lambda, sigma, callbacks...`_`)`
2384+
2385+
In that call, `lambda` should be a column vector of the same type as
2386+
`coordinates`, and `sigma` is a `double`. `lambda` and `sigma` will be
2387+
overwritten with the final values of the Lagrange multipliers and penalty
2388+
parameters.
2389+
2390+
If `lambda` and `sigma` are not specified, then 0 is used as the initial value
2391+
for all Lagrange multipliers and 10 is used as the initial penalty parameter.
2392+
24032393
#### See also:
24042394

24052395
* [A Nonlinear Programming Algorithm for Solving Semidefinite Programs via Low-rank Factorization](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.682.1520&rep=rep1&type=pdf)

include/ensmallen.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
#include "ensmallen_bits/utility/proxies.hpp"
8282
#include "ensmallen_bits/utility/function_traits.hpp"
8383
#include "ensmallen_bits/utility/using.hpp"
84+
#include "ensmallen_bits/utility/detect_callbacks.hpp"
8485
#include "ensmallen_bits/utility/indicators/epsilon.hpp"
8586
#include "ensmallen_bits/utility/indicators/igd.hpp"
8687
#include "ensmallen_bits/utility/indicators/igd_plus.hpp"

include/ensmallen_bits/aug_lagrangian/aug_lagrangian.hpp

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ namespace ens {
3030
* documentation on function types included with this distribution or on the
3131
* ensmallen website.
3232
*/
33-
template<typename VecType = arma::vec>
33+
template<typename VecType = arma::vec> // TODO: remove for ensmallen 4.x
3434
class AugLagrangianType
3535
{
3636
public:
@@ -50,7 +50,7 @@ class AugLagrangianType
5050
const L_BFGS& lbfgs = L_BFGS());
5151

5252
/**
53-
* Optimize the function. The value '1' is used for the initial value of each
53+
* Optimize the function. The value '0' is used for the initial value of each
5454
* Lagrange multiplier. To set the Lagrange multipliers yourself, use the
5555
* other overload of Optimize().
5656
*
@@ -67,7 +67,8 @@ class AugLagrangianType
6767
typename MatType,
6868
typename GradType,
6969
typename... CallbackTypes>
70-
typename std::enable_if<IsMatrixType<GradType>::value, bool>::type
70+
typename std::enable_if<IsMatrixType<GradType>::value &&
71+
IsAllNonMatrix<CallbackTypes...>::value, bool>::type
7172
Optimize(LagrangianFunctionType& function,
7273
MatType& coordinates,
7374
CallbackTypes&&... callbacks);
@@ -76,9 +77,10 @@ class AugLagrangianType
7677
template<typename LagrangianFunctionType,
7778
typename MatType,
7879
typename... CallbackTypes>
79-
bool Optimize(LagrangianFunctionType& function,
80-
MatType& coordinates,
81-
CallbackTypes&&... callbacks)
80+
typename std::enable_if<IsAllNonMatrix<CallbackTypes...>::value, bool>::type
81+
Optimize(LagrangianFunctionType& function,
82+
MatType& coordinates,
83+
CallbackTypes&&... callbacks)
8284
{
8385
return Optimize<LagrangianFunctionType, MatType, MatType,
8486
CallbackTypes...>(function, coordinates,
@@ -97,26 +99,50 @@ class AugLagrangianType
9799
* @tparam CallbackTypes Types of callback functions.
98100
* @param function The function to optimize.
99101
* @param coordinates Output matrix to store the optimized coordinates in.
100-
* @param initLambda Vector of initial Lagrange multipliers. Should have
101-
* length equal to the number of constraints.
102-
* @param initSigma Initial penalty parameter.
102+
* @param lambda Vector containing initial Lagrange multipliers. Should have
103+
* length equal to the number of constraints. This will be overwritten
104+
* with the Lagrange multipliers that are found during optimization.
105+
* @param sigma Initial penalty parameter. This will be overwritten with the
106+
* final penalty value used during optimization.
103107
* @param callbacks Callback functions.
104108
*/
105109
template<typename LagrangianFunctionType,
106110
typename MatType,
111+
typename InVecType,
107112
typename GradType,
108113
typename... CallbackTypes>
114+
[[deprecated("use Optimize() with non-const lambda/sigma instead")]]
109115
typename std::enable_if<IsMatrixType<GradType>::value, bool>::type
110116
Optimize(LagrangianFunctionType& function,
111117
MatType& coordinates,
112-
const VecType& initLambda,
118+
const InVecType& initLambda,
113119
const double initSigma,
120+
CallbackTypes&&... callbacks)
121+
{
122+
deprecatedLambda = initLambda;
123+
deprecatedSigma = initSigma;
124+
const bool result = Optimize(function, coordinates, this->deprecatedLambda,
125+
this->deprecatedSigma,
126+
std::forward<CallbackTypes>(callbacks)...);
127+
}
128+
129+
template<typename LagrangianFunctionType,
130+
typename MatType,
131+
typename InVecType,
132+
typename GradType,
133+
typename... CallbackTypes>
134+
typename std::enable_if<IsMatrixType<GradType>::value, bool>::type
135+
Optimize(LagrangianFunctionType& function,
136+
MatType& coordinates,
137+
InVecType& lambda,
138+
double& sigma,
114139
CallbackTypes&&... callbacks);
115140

116141
//! Forward the MatType as GradType.
117142
template<typename LagrangianFunctionType,
118143
typename MatType,
119144
typename... CallbackTypes>
145+
[[deprecated("use Optimize() with non-const lambda/sigma instead")]]
120146
bool Optimize(LagrangianFunctionType& function,
121147
MatType& coordinates,
122148
const VecType& initLambda,
@@ -128,20 +154,39 @@ class AugLagrangianType
128154
std::forward<CallbackTypes>(callbacks)...);
129155
}
130156

157+
template<typename LagrangianFunctionType,
158+
typename MatType,
159+
typename InVecType,
160+
typename... CallbackTypes>
161+
bool Optimize(LagrangianFunctionType& function,
162+
MatType& coordinates,
163+
InVecType& lambda,
164+
double& sigma,
165+
CallbackTypes&&... callbacks)
166+
{
167+
return Optimize<LagrangianFunctionType, MatType, InVecType, MatType,
168+
CallbackTypes...>(function, coordinates, lambda, sigma,
169+
std::forward<CallbackTypes>(callbacks)...);
170+
}
171+
131172
//! Get the L-BFGS object used for the actual optimization.
132173
const L_BFGS& LBFGS() const { return lbfgs; }
133174
//! Modify the L-BFGS object used for the actual optimization.
134175
L_BFGS& LBFGS() { return lbfgs; }
135176

136177
//! Get the Lagrange multipliers.
137-
const VecType& Lambda() const { return lambda; }
178+
[[deprecated("use Optimize() with lambda/sigma parameters instead")]]
179+
const VecType& Lambda() const { return deprecatedLambda; }
138180
//! Modify the Lagrange multipliers (i.e. set them before optimization).
139-
VecType& Lambda() { return lambda; }
181+
[[deprecated("use Optimize() with lambda/sigma parameters instead")]]
182+
VecType& Lambda() { return deprecatedLambda; }
140183

141184
//! Get the penalty parameter.
142-
double Sigma() const { return sigma; }
185+
[[deprecated("use Optimize() with lambda/sigma parameters instead")]]
186+
double Sigma() const { return deprecatedSigma; }
143187
//! Modify the penalty parameter.
144-
double& Sigma() { return sigma; }
188+
[[deprecated("use Optimize() with lambda/sigma parameters instead")]]
189+
double& Sigma() { return deprecatedSigma; }
145190

146191
//! Get the maximum iterations
147192
size_t MaxIterations() const { return maxIterations; }
@@ -174,35 +219,37 @@ class AugLagrangianType
174219
//! Controls early termination of the optimization process.
175220
bool terminate;
176221

222+
// NOTE: these will be removed in ensmallen 4.x!
177223
//! Lagrange multipliers.
178-
VecType lambda;
179-
224+
VecType deprecatedLambda;
180225
//! Penalty parameter.
181-
double sigma;
226+
double deprecatedSigma;
182227

183228
/**
184229
* Internal optimization function: given an initialized AugLagrangianFunction,
185230
* perform the optimization itself.
186231
*/
187232
template<typename LagrangianFunctionType,
188233
typename MatType,
234+
typename InVecType,
189235
typename GradType,
190236
typename... CallbackTypes>
191237
typename std::enable_if<IsMatrixType<GradType>::value, bool>::type
192-
Optimize(AugLagrangianFunction<LagrangianFunctionType, VecType>& augfunc,
238+
Optimize(AugLagrangianFunction<LagrangianFunctionType, InVecType>& augfunc,
193239
MatType& coordinates,
194240
CallbackTypes&&... callbacks);
195241

196242
//! Forward the MatType as GradType.
197243
template<typename LagrangianFunctionType,
198244
typename MatType,
245+
typename InVecType,
199246
typename... CallbackTypes>
200247
bool Optimize(
201-
AugLagrangianFunction<LagrangianFunctionType, VecType>& function,
248+
AugLagrangianFunction<LagrangianFunctionType, InVecType>& function,
202249
MatType& coordinates,
203250
CallbackTypes&&... callbacks)
204251
{
205-
return Optimize<LagrangianFunctionType, MatType, MatType,
252+
return Optimize<LagrangianFunctionType, MatType, InVecType, MatType,
206253
CallbackTypes...>(function, coordinates,
207254
std::forward<CallbackTypes>(callbacks)...);
208255
}

0 commit comments

Comments
 (0)