C++ API Reference

namespace quala

Typedefs

using real_t = double

Default floating point type.

using realvec = Eigen::Matrix<real_t, Eigen::Dynamic, 1>

Default type for floating point vectors.

using realmat = Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic>

Default type for floating point matrices.

using vec = realvec

Default type for vectors.

using rvec = Eigen::Ref<vec>

Default type for mutable references to vectors.

using crvec = Eigen::Ref<const vec>

Default type for immutable references to vectors.

using mat = realmat

Default type for matrices.

using rmat = Eigen::Ref<mat>

Default type for mutable references to matrices.

using crmat = Eigen::Ref<const mat>

Default type for immutable references to matrices.

using index_t = Eigen::Index

Default type for vector indices.

using length_t = index_t

Default type for vector sizes.

using idvec = Eigen::Matrix<index_t, Eigen::Dynamic, 1>

Type for a vector of indices.

using ridvec = Eigen::Ref<idvec>

Mutable reference to vector indices.

using cridvec = Eigen::Ref<const idvec>

Immutable reference to vector indices.

template<class Derived>
using anymat = Eigen::MatrixBase<Derived>

Generic type for vector and matrix arguments.

Functions

inline void minimize_update_anderson(LimitedMemoryQR &qr, rmat G, crvec rₖ, crvec rₖ₋₁, crvec gₖ, rvec γ_LS, rvec xₖ_aa)

Solve one step of Anderson acceleration to find a fixed point of a function g(x):

\( g(x^\star) - x^\star = 0 \)

Updates the QR factorization of \( \mathcal{R}_k = QR \), solves the least squares problem to find \( \gamma_\text{LS} \), computes the next iterate \( x_{k+1} \), and stores the current function value \( g_k \) in the matrix \( G \), which is used as a circular buffer.

\[\begin{split} \begin{aligned} \mathcal{R}_k &= \begin{pmatrix} \Delta r_{k-m_k} & \dots & \Delta r_{k-1} \end{pmatrix} \in \mathbb{R}^{n\times m_k} \\ \Delta r_i &= r_{i+1} - r_i \\ r_i &= g_i - x_i \\ g_i &= g(x_i) \\ \DeclareMathOperator*{\argmin}{argmin} \gamma_\text{LS} &= \argmin_\gamma \left\| \mathcal{R}_k \gamma - r_k \right\|_2 \\ \alpha_i &= \begin{cases} \gamma_\text{LS}[0] & i = 0 \\ \gamma_\text{LS}[i] - \gamma_\text{LS}[i-1] & 0 < i < m_k \\ 1 - \gamma_\text{LS}[m_k - 1] & i = m_k \end{cases} \\ x_{k+1} &= \sum_{i=0}^{m_k} \alpha_i\,g_i \end{aligned} \end{split}\]

Variables

constexpr real_t inf = std::numeric_limits<real_t>::infinity()

\( \infty \)

constexpr real_t NaN = std::numeric_limits<real_t>::quiet_NaN()

Not a number.

class AndersonAccel
#include <quala/anderson-acceleration.hpp>

Anderson Acceleration.

Todo:

Condition estimation of the QR factorization.

Public Types

using Params = AndersonAccelParams

Public Functions

inline AndersonAccel(Params params)
Parameters

params – Parameters.

inline AndersonAccel(Params params, length_t n)
Parameters
  • params – Parameters.

  • n – Problem dimension (size of the vectors).

inline void resize(length_t n)

Change the problem dimension.

Flushes the history.

Parameters

n – Problem dimension (size of the vectors).

inline void initialize(crvec g₀, vec r₀)

Call this function on the first iteration to initialize the accelerator.

inline void compute(crvec gₖ, crvec rₖ, rvec xₖ_aa)

Compute the accelerated iterate \( x^k_\text{AA} \), given the function value at the current iterate \( g^k = g(x^k) \) and the corresponding residual \( r^k = g^k - x^k \).

inline void compute(crvec gₖ, vec &&rₖ, rvec xₖ_aa)

Compute the accelerated iterate \( x^k_\text{AA} \), given the function value at the current iterate \( g^k = g(x^k) \) and the corresponding residual \( r^k = g^k - x^k \).

inline void reset()

Reset the accelerator (but keep the last function value and residual, so calling initialize is not necessary).

inline length_t n() const

Get the problem dimension.

inline length_t history() const

Get the maximum number of stored columns.

inline length_t current_history() const

Get the number of columns currently stored in the buffer.

inline const Params &get_params() const

Get the parameters.

struct AndersonAccelParams
#include <quala/anderson-acceleration.hpp>

Parameters for the AndersonAccel class.

Public Members

length_t memory = 10

Length of the history to keep (the number of columns in the QR factorization).

If this number is greater than the problem dimension, the memory is set to the problem dimension (otherwise the system is underdetermined).

class BroydenGood
#include <quala/broyden-good.hpp>

Broyden’s “Good” method for solving systems of nonlinear equations \( F(x) = 0 \).

\[\begin{split} \begin{aligned} B_{k+1} &= B_k + \frac{\left(y_k - B_k s_k\right) s_k^\top} {s_k^\top s_k} \\ H_{k+1} &= H_k + \frac{\left(s_k - H_k y_k\right) \left(s_k^\top H_k\right)} {s_k^\top H_k y_k} \\ s_k &\triangleq x_{k+1} - x_k \\ y_k &\triangleq F(x_{k+1}) - F(x_k) \\ \end{aligned} \end{split}\]
Where \( B_k \) approximates the Jacobian of \( F(x_k) \) and \( H_k \triangleq B_k^{-1} \).

Todo:

Damping.

Public Types

using Params = BroydenGoodParams

Public Functions

inline BroydenGood(Params params)
inline BroydenGood(Params params, length_t n)
template<class VecS, class VecY>
bool update_sy(const anymat<VecS> &s, const anymat<VecY> &y, bool forced = false)

Update the inverse Jacobian approximation using the new vectors sₖ = xₖ₊₁ - xₖ and yₖ = pₖ₊₁ - pₖ.

inline bool update(crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁, bool forced = false)

Update the inverse Jacobian approximation using the new vectors xₖ₊₁ and pₖ₊₁.

inline bool apply(rvec q, real_t γ)

Apply the inverse Jacobian approximation to the given vector q, i.e.

\( q \leftarrow H_k q \). Initial inverse Hessian approximation is set to \( H_0 = \gamma I \). The result is scaled by a factor γ. If γ is negative, the result is scaled by \( \frac{s^\top y}{y^\top y} \).

inline void reset()

Throw away the approximation and all previous vectors s and y.

inline void resize(length_t n)

Re-allocate storage for a problem with a different size.

Causes a reset.

inline const Params &get_params() const

Get the parameters.

inline length_t n() const

Get the size of the s and y vectors in the buffer.

inline length_t history() const

Get the number of previous vectors s and y stored in the buffer.

inline index_t succ(index_t i) const

Get the next index in the circular buffer of previous s and y vectors.

inline index_t pred(index_t i) const

Get the previous index in the circular buffer of s and y vectors.

inline length_t current_history() const

Get the number of previous s and y vectors currently stored in the buffer.

inline auto s(index_t i)
inline auto s(index_t i) const
inline auto (index_t i)
inline auto (index_t i) const
template<class F>
inline void foreach_fwd(const F &fun) const

Iterate over the indices in the history buffer, oldest first.

template<class F>
inline void foreach_rev(const F &fun) const

Iterate over the indices in the history buffer, newest first.

struct BroydenGoodParams
#include <quala/broyden-good.hpp>

Parameters for the BroydenGood class.

Public Members

length_t memory = 10

Length of the history to keep.

real_t min_div_abs = 1e-32

Reject update if \( s^\top Hy \le \text{min_div_fac} \).

bool force_pos_def = false

If set to true, the inverse Jacobian estimate should remain definite.

bool restarted = true

If set to true, the buffer is cleared after memory iterations.

If set to false, a circular buffer is used, replacing the oldest pair of vectors, as a limited-memory type algorithm. However, since each vector s̃ depends on the previous vectors, this algorithm is not theoretically correct, because the s̃ vectors are not updated when the old history is overwritten.

real_t powell_damping_factor = 0

Powell’s trick, damping, prevents nonsingularity.

struct BroydenStorage
#include <quala/broyden-good.hpp>

Layout:

    ┌───── 2 m + 1 ─────┐
  ┌ ┌───┬───┬───┬───┬───┐
  │ │   │   │   │   │   │
n │ │ s │ s̃ │ s │ s̃ │ w │
  │ │   │   │   │   │   │
  └ └───┴───┴───┴───┴───┘

Public Types

using storage_t = Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>

Public Functions

inline void resize(length_t n, length_t history)

Re-allocate storage for a problem with a different size.

inline length_t n() const

Get the size of the s and s̃ vectors in the buffer.

inline length_t history() const

Get the number of previous vectors s and s̃ stored in the buffer.

inline auto s(index_t i)
inline auto s(index_t i) const
inline auto (index_t i)
inline auto (index_t i) const
inline auto work()
inline auto work() const

Public Members

storage_t sto
template<class IndexT = size_t>
struct CircularIndexIterator
#include <quala/util/ringbuffer.hpp>

Public Types

using Index = IndexT
using Indices = CircularIndices<Index>
using value_type = Indices
using reference = value_type
using difference_type = std::ptrdiff_t
using pointer = void
using iterator_category = std::input_iterator_tag

Public Functions

inline CircularIndexIterator()
inline CircularIndexIterator(Indices i, Index max)
inline reference operator*() const
inline CircularIndexIterator &operator++()
inline CircularIndexIterator &operator--()
inline CircularIndexIterator operator++(int)
inline CircularIndexIterator operator--(int)

Public Members

Indices i
Index max
template<class IndexT>
bool operator==(CircularIndexIterator<IndexT> a, CircularIndexIterator<IndexT> b)

Note

Only valid for two indices in the same range.

template<class IndexT>
bool operator!=(CircularIndexIterator<IndexT> a, CircularIndexIterator<IndexT> b)

Note

Only valid for two indices in the same range.

template<class IndexT = size_t>
struct CircularIndices
#include <quala/util/ringbuffer.hpp>

Public Types

using Index = IndexT

Public Functions

inline CircularIndices(Index zerobased, Index circular)

Public Members

Index zerobased
Index circular
template<class IndexT>
bool operator==(CircularIndices<IndexT> a, CircularIndices<IndexT> b)

Note

Only valid for two indices in the same range.

template<class IndexT>
bool operator!=(CircularIndices<IndexT> a, CircularIndices<IndexT> b)

Note

Only valid for two indices in the same range.

template<class IndexT>
class CircularRange
#include <quala/util/ringbuffer.hpp>

Public Types

using Index = IndexT
using Indices = CircularIndices<Index>
using const_iterator = CircularIndexIterator<Index>
using iterator = const_iterator
using const_reverse_iterator = ReverseCircularIndexIterator<Index>
using reverse_iterator = const_reverse_iterator

Public Functions

inline CircularRange(Index size, Index idx1, Index idx2, Index max)
inline iterator begin() const
inline iterator end() const
inline const_iterator cbegin() const
inline const_iterator cend() const
inline reverse_iterator rbegin() const
inline reverse_iterator rend() const
inline const_reverse_iterator crbegin() const
inline const_reverse_iterator crend() const
class LBFGS
#include <quala/decl/lbfgs.hpp>

Limited memory Broyden–Fletcher–Goldfarb–Shanno (L-BFGS) algorithm.

Public Types

enum class Sign

The sign of the vectors \( p \) passed to the LBFGS::update method.

Values:

enumerator Positive

\( p \sim \nabla \psi(x) \)

enumerator Negative

\( p \sim -\nabla \psi(x) \)

using Params = LBFGSParams

Public Functions

inline LBFGS(Params params)
inline LBFGS(Params params, length_t n)
template<class VecS, class VecY>
inline bool update_sy(const anymat<VecS> &s, const anymat<VecY> &y, real_t pₖ₊₁ᵀpₖ₊₁, bool forced = false)

Update the inverse Hessian approximation using the new vectors sₖ = xₖ₊₁ - xₖ and yₖ = pₖ₊₁ - pₖ.

inline bool update(crvec xₖ, crvec xₖ₊₁, crvec pₖ, crvec pₖ₊₁, Sign sign = Sign::Positive, bool forced = false)

Update the inverse Hessian approximation using the new vectors xₖ₊₁ and pₖ₊₁.

inline bool apply(rvec q, real_t γ = -1)

Apply the inverse Hessian approximation to the given vector q.

Initial inverse Hessian approximation is set to \( H_0 = \gamma I \). If γ is negative, \( H_0 = \frac{s^\top y}{y^\top y} I \).

template<class IndexVec>
bool apply(rvec q, real_t γ, const IndexVec &J)

Apply the inverse Hessian approximation to the given vector q, applying only the columns and rows of the Hessian in the index set J.

inline void reset()

Throw away the approximation and all previous vectors s and y.

inline void resize(length_t n)

Re-allocate storage for a problem with a different size.

Causes a reset.

inline void scale_y(real_t factor)

Scale the stored y vectors by the given factor.

inline const Params &get_params() const

Get the parameters.

inline length_t n() const

Get the size of the s and y vectors in the buffer.

inline length_t history() const

Get the number of previous vectors s and y stored in the buffer.

inline index_t succ(index_t i) const

Get the next index in the circular buffer of previous s and y vectors.

inline index_t pred(index_t i) const

Get the previous index in the circular buffer of s and y vectors.

inline length_t current_history() const

Get the number of previous s and y vectors currently stored in the buffer.

inline auto s(index_t i)
inline auto s(index_t i) const
inline auto y(index_t i)
inline auto y(index_t i) const
inline real_t &ρ(index_t i)
inline const real_t &ρ(index_t i) const
inline real_t &α(index_t i)
inline const real_t &α(index_t i) const
template<class F>
inline void foreach_fwd(const F &fun) const

Iterate over the indices in the history buffer, oldest first.

template<class F>
inline void foreach_rev(const F &fun) const

Iterate over the indices in the history buffer, newest first.

Public Static Functions

static inline bool update_valid(const LBFGSParams &params, real_t yᵀs, real_t sᵀs, real_t pᵀp)

Check if the new vectors s and y allow for a valid BFGS update that preserves the positive definiteness of the Hessian approximation.

struct LBFGSParams
#include <quala/decl/lbfgs.hpp>

Parameters for the LBFGS class.

Public Members

length_t memory = 10

Length of the history to keep.

real_t min_div_fac = 1e-10

Reject update if \( y^\top s \le \text{min_div_fac} \cdot s^\top s \).

real_t min_abs_s = 1e-32

Reject update if \( s^\top s \le \text{min_abs_s} \).

CBFGSParams cbfgs

Parameters in the cautious BFGS update condition.

\[ \frac{y^\top s}{s^\top s} \ge \epsilon \| g \|^\alpha \]

bool force_pos_def = true

If set to true, the inverse Hessian estimate should remain definite, i.e.

a check is performed that rejects the update if \( y^\top s \le \text{min_div_fac} \cdot s^\top s \). If set to false, just try to prevent a singular Hessian by rejecting the update if \( \left| y^\top s \right| \le \text{min_div_fac} \cdot s^\top s \).

struct CBFGSParams
#include <quala/decl/lbfgs.hpp>

Cautious BFGS update.

See also

cbfgs

Public Functions

inline explicit operator bool() const

Public Members

real_t α = 1
real_t ϵ = 0

Set to zero to disable CBFGS check.

struct LBFGSStorage
#include <quala/decl/lbfgs.hpp>

Layout:

      ┌───── 2 m ─────┐
    ┌ ┌───┬───┬───┬───┐
    │ │   │   │   │   │
    │ │ s │ y │ s │ y │
n+1 │ │   │   │   │   │
    │ ├───┼───┼───┼───┤
    │ │ ρ │ α │ ρ │ α │
    └ └───┴───┴───┴───┘

Public Types

using storage_t = Eigen::Matrix<real_t, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>

Public Functions

inline void resize(length_t n, length_t history)

Re-allocate storage for a problem with a different size.

inline length_t n() const

Get the size of the s and y vectors in the buffer.

inline length_t history() const

Get the number of previous vectors s and y stored in the buffer.

inline auto s(index_t i)
inline auto s(index_t i) const
inline auto y(index_t i)
inline auto y(index_t i) const
inline real_t &ρ(index_t i)
inline const real_t &ρ(index_t i) const
inline real_t &α(index_t i)
inline const real_t &α(index_t i) const

Public Members

storage_t sto
class LimitedMemoryQR
#include <quala/detail/limited-memory-qr.hpp>

Incremental QR factorization using modified Gram-Schmidt with reorthogonalization.

Computes A = QR while allowing efficient removal of the first column of A or adding new columns at the end of A.

Public Types

template<class Derived>
using solve_ret_t = std::conditional_t<Eigen::internal::traits<Derived>::ColsAtCompileTime == 1, vec, mat>

Public Functions

LimitedMemoryQR() = default
inline LimitedMemoryQR(length_t n, length_t m)

The maximum dimensions of Q are n×m and the maximum dimensions of R are m×m.

Parameters
  • n – The size of the vectors, the number of rows of A.

  • m – The maximum number of columns of A.

inline length_t n() const
inline length_t m() const
inline length_t size() const
inline length_t history() const
template<class VecV>
inline void add_column(const VecV &v)

Add the given column to the right.

inline void remove_column()

Remove the leftmost column.

template<class VecB, class VecX>
inline void solve_col(const VecB &b, VecX &x) const

Solve the least squares problem Ax = b.

template<class MatB, class MatX>
inline void solve(const MatB &B, MatX &X) const

Solve the least squares problem AX = B.

template<class Derived>
inline solve_ret_t<Derived> solve(const Eigen::DenseBase<Derived> &B)

Solve the least squares problem AX = B.

inline const mat &get_raw_Q() const

Get the full, raw storage for the orthogonal matrix Q.

inline const mat &get_raw_R() const

Get the full, raw storage for the upper triangular matrix R.

The columns of this matrix are permuted because it’s stored as a circular buffer for efficiently appending columns to the end and popping columns from the front.

inline mat get_full_R() const

Get the full storage for the upper triangular matrix R but with the columns in the correct order.

Note

Meant for tests only, creates a permuted copy.

inline mat get_R() const

Get the matrix R such that Q times R is the original matrix.

Note

Meant for tests only, creates a permuted copy.

inline mat get_Q() const

Get the matrix Q such that Q times R is the original matrix.

Note

Meant for tests only, creates a copy.

inline void scale_R(real_t scal)

Multiply the matrix R by a scalar.

inline unsigned long get_reorth_count() const

Get the number of MGS reorthogonalizations.

inline void clear_reorth_count()

Reset the number of MGS reorthogonalizations.

inline void reset()

Reset all indices, clearing the Q and R matrices.

inline void resize(length_t n, length_t m)

Re-allocate storage for a problem with a different size.

Causes a reset.

inline length_t num_columns() const

Get the number of columns that are currently stored.

inline index_t ring_head() const

Get the head index of the circular buffer (points to the oldest element).

inline index_t ring_tail() const

Get the tail index of the circular buffer (points to one past the most recent element).

inline index_t ring_next(index_t i) const

Get the next index in the circular buffer.

inline index_t ring_prev(index_t i) const

Get the previous index in the circular buffer.

inline length_t current_history() const

Get the number of columns currently stored in the buffer.

inline CircularRange<index_t> ring_iter() const

Get iterators in the circular buffer.

inline ReverseCircularRange<index_t> ring_reverse_iter() const

Get reverse iterators in the circular buffer.

template<class T>
class MaxHistory
#include <quala/util/ringbuffer.hpp>

Public Functions

inline MaxHistory(size_t memory)
inline void add(T newt)
inline const T &max() const
template<class IndexT = size_t>
struct ReverseCircularIndexIterator
#include <quala/util/ringbuffer.hpp>

Public Types

using ForwardIterator = CircularIndexIterator<IndexT>
using Index = typename ForwardIterator::Index
using Indices = typename ForwardIterator::Indices
using value_type = Indices
using reference = value_type
using difference_type = std::ptrdiff_t
using pointer = void
using iterator_category = std::input_iterator_tag

Public Functions

inline ReverseCircularIndexIterator()
inline ReverseCircularIndexIterator(Indices i, Index max)
inline ReverseCircularIndexIterator(ForwardIterator forwardit)
inline reference operator*() const
inline ReverseCircularIndexIterator &operator++()
inline ReverseCircularIndexIterator &operator--()
inline ReverseCircularIndexIterator operator++(int)
inline ReverseCircularIndexIterator operator--(int)

Public Members

ForwardIterator forwardit
template<class IndexT>
bool operator==(ReverseCircularIndexIterator<IndexT> a, ReverseCircularIndexIterator<IndexT> b)

Note

Only valid for two indices in the same range.

template<class IndexT>
bool operator!=(ReverseCircularIndexIterator<IndexT> a, ReverseCircularIndexIterator<IndexT> b)

Note

Only valid for two indices in the same range.

template<class IndexT>
class ReverseCircularRange
#include <quala/util/ringbuffer.hpp>

Public Types

using ForwardRange = CircularRange<IndexT>
using Index = typename ForwardRange::Index
using Indices = typename ForwardRange::Indices
using const_iterator = typename ForwardRange::const_reverse_iterator
using iterator = typename ForwardRange::reverse_iterator
using const_reverse_iterator = typename ForwardRange::const_iterator
using reverse_iterator = typename ForwardRange::iterator

Public Functions

inline ReverseCircularRange(const ForwardRange &forwardrange)
inline ReverseCircularRange(Index size, Index idx1, Index idx2, Index max)
inline iterator begin() const
inline iterator end() const
inline const_iterator cbegin() const
inline const_iterator cend() const
inline reverse_iterator rbegin() const
inline reverse_iterator rend() const
inline const_reverse_iterator crbegin() const
inline const_reverse_iterator crend() const
class vec_allocator
#include <quala/util/alloc.hpp>

Public Functions

inline vec_allocator(size_t num_vec, Eigen::Index n)
vec_allocator(const vec_allocator&) = delete
vec_allocator(vec_allocator&&) = delete
vec_allocator &operator=(const vec_allocator&) = delete
vec_allocator &operator=(vec_allocator&&) = delete
inline auto alloc()
inline alloc_raii_wrapper alloc_raii()
inline void free(rvec v)
template<class ...Vecs>
inline void free(rvec first, Vecs&&... vecs)
inline size_t size() const
inline size_t used_space() const
inline Eigen::Index vector_size() const
inline size_t highwater() const
struct alloc_raii_wrapper
#include <quala/util/alloc.hpp>

Public Types

using mvec = Eigen::Map<vec>

Public Functions

inline alloc_raii_wrapper(real_t *dptr, Eigen::Index n, vec_allocator *alloc)
inline alloc_raii_wrapper(mvec &&v, vec_allocator *alloc)
inline ~alloc_raii_wrapper()
alloc_raii_wrapper(const alloc_raii_wrapper&) = delete
inline alloc_raii_wrapper(alloc_raii_wrapper &&o) noexcept
alloc_raii_wrapper &operator=(const alloc_raii_wrapper&) = delete
inline alloc_raii_wrapper &operator=(alloc_raii_wrapper &&o) noexcept
inline alloc_raii_wrapper &operator=(crvec v)
inline operator crvec() const
inline operator rvec()

Public Members

mvec v
vec_allocator *alloc
namespace vec_util

Functions

template<class V, class M>
auto norm_squared_weighted(V &&v, M &&Σ)

Get the Σ norm squared of a given vector, with Σ a diagonal matrix.

Returns

\( \langle v, \Sigma v \rangle \)

template<class Vec>
real_t norm_inf(const Vec &v)

Get the maximum or infinity-norm of the given vector.

Returns

\( \left\|v\right\|_\infty \)

template<class Vec>
real_t norm_1(const Vec &v)

Get the 1-norm of the given vector.

Returns

\( \left\|v\right\|_1 \)