Dem Bones  1.2.0
Skinning Decomposition Library
Dem::ConvexLS< _Scalar > Class Template Reference

Linear least squares solver with non-negativity constraint and optional affinity constraint. More...

#include "DemBones/ConvexLS.h"

Public Types

using MatrixX = Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic >
 
using VectorX = Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 >
 

Public Member Functions

 ConvexLS (int maxSize=1)
 
void init (int maxSize)
 
void solve (const MatrixX &aTa, const VectorX &aTb, VectorX &x, bool affine, bool warmStart=false)
 

Detailed Description

template<class _Scalar>
class Dem::ConvexLS< _Scalar >

Linear least squares solver with non-negativity constraint and optional affinity constraint.

Solve:

\begin{eqnarray*} min &||Ax-b||^2 \\ \mbox{Subject to: } & x(0).. x(n-1) \geq 0, \\ \mbox{(optional) } & x(0) +.. + x(n-1) = 1 \end{eqnarray*}

The solver implements active set method to handle non-negativity constraint and QR decomposition to handle affinity constraint.

_Scalar is the floating-point data type.

Definition at line 31 of file ConvexLS.h.

Member Typedef Documentation

◆ MatrixX

template<class _Scalar >
using Dem::ConvexLS< _Scalar >::MatrixX = Eigen::Matrix<_Scalar, Eigen::Dynamic, Eigen::Dynamic>

Definition at line 34 of file ConvexLS.h.

◆ VectorX

template<class _Scalar >
using Dem::ConvexLS< _Scalar >::VectorX = Eigen::Matrix<_Scalar, Eigen::Dynamic, 1>

Definition at line 35 of file ConvexLS.h.

Constructor & Destructor Documentation

◆ ConvexLS()

template<class _Scalar >
Dem::ConvexLS< _Scalar >::ConvexLS ( int  maxSize = 1)
inline

Constructor, just call init()

Parameters
[in]maxSizeis the maximum size of the unknown \( x \) if the affinity constraint is imposed.

Definition at line 40 of file ConvexLS.h.

40  {
41  q2.resize(0);
42  init(maxSize);
43  }

Member Function Documentation

◆ init()

template<class _Scalar >
void Dem::ConvexLS< _Scalar >::init ( int  maxSize)
inline

Init matrices \( Q \) in the QR decomposition used for affinity constraint

Parameters
[in]maxSizeis the maximum size of the unknown \( x \) if the affinity constraint is imposed.

Definition at line 48 of file ConvexLS.h.

48  {
49  int curN=(int)q2.size()+1;
50  if (curN<maxSize) {
51  q2.resize(maxSize-1);
52  #pragma omp parallel for
53  for (int n=curN-1; n<maxSize-1; n++)
54  q2[n]=MatrixX(VectorX::Constant(n+2, _Scalar(1)).householderQr().householderQ()).rightCols(n+1);
55  }
56  }

◆ solve()

template<class _Scalar >
void Dem::ConvexLS< _Scalar >::solve ( const MatrixX aTa,
const VectorX aTb,
VectorX x,
bool  affine,
bool  warmStart = false 
)
inline

Solve the least squares problem

Parameters
[in]aTais the cross product matrix \( A^TA \)
[in]aTbis the vector \( A^Tb \)
[in,out]xis the by-reference output and it is also the init solution (if warmStart == true)
[in]affine=truewill impose affinity constraint
[in]warmStart=truewill initialize the solution by x

Definition at line 65 of file ConvexLS.h.

65  {
66  int n=int(aTa.cols());
67 
68  if (!warmStart) x=VectorX::Constant(n, _Scalar(1)/n);
69 
70  Eigen::ArrayXi idx(n);
71  int np=0;
72  for (int i=0; i<n; i++)
73  if (x(i)>0) idx[np++]=i; else idx[n-i+np-1]=i;
74 
75  VectorX p;
76 
77  for (int rep=0; rep<n; rep++) {
78  solveP(aTa, aTb, x, idx, np, affine, p);
79 
80  if ((indexing_vector(x, idx.head(np))+indexing_vector(p, idx.head(np))).minCoeff()>=0) {
81  x+=p;
82  if (np==n) break;
83  Eigen::Index iMax;
84  (indexing_vector(aTb, idx.tail(n-np))-indexing_row(aTa, idx.tail(n-np))*x).maxCoeff(&iMax);
85  std::swap(idx[iMax+np], idx[np]);
86  np++;
87  } else {
88  _Scalar alpha;
89  int iMin=-1;
90  for (int i=0; i<np; i++)
91  if (p(idx[i])<0) {
92  if ((iMin==-1)||(x(idx[i])<-alpha*p(idx[i]))) {
93  alpha=-x(idx[i])/p(idx[i]);
94  iMin=i;
95  }
96  }
97  x+=alpha*p;
98  _Scalar eps=std::abs(x(idx[iMin]));
99  x(idx[iMin])=0;
100  for (int i=0; i<np; i++)
101  if (x(idx[i])<=eps) std::swap(idx[i--], idx[--np]);
102  }
103  if (affine) x/=x.sum();
104  }
105  }

The documentation for this class was generated from the following file:
Dem::indexing_row
Eigen::CwiseNullaryOp< indexing_functor_row< ArgType, RowIndexType >, typename indexing_functor_row< ArgType, RowIndexType >::MatrixType > indexing_row(const Eigen::MatrixBase< ArgType > &arg, const RowIndexType &row_indices)
Definition: Indexing.h:81
Dem::ConvexLS::MatrixX
Eigen::Matrix< _Scalar, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Definition: ConvexLS.h:34
Dem::ConvexLS::init
void init(int maxSize)
Definition: ConvexLS.h:48
Dem::indexing_vector
Eigen::CwiseNullaryOp< indexing_functor_vector< ArgType, IndexType >, typename indexing_functor_vector< ArgType, IndexType >::VectorType > indexing_vector(const Eigen::MatrixBase< ArgType > &arg, const IndexType &indices)
Definition: Indexing.h:115
Dem::ConvexLS::VectorX
Eigen::Matrix< _Scalar, Eigen::Dynamic, 1 > VectorX
Definition: ConvexLS.h:35