2 import numpy.linalg 
as npl
 
    6 This file implements a sparse linear problem (quadric cost, linear constraints -- LCQP) 
    7 where the decision variables are denoted by x=(x1 ... xn), n being the number of 
    9 The problem can be written: 
   10   min      Sum_i=1^p  || A_i x - b_i ||^2 
   13 so that    forall j=1:q   C_j x = d_i 
   15 Matrices A_i and C_j are block sparse, i.e. they are acting only on some (few) of the 
   18 The file implements the main class FactorGraph, which stores the LCQP problem and solve 
   20 It also provides a secondary class Factor, used to set up FactorGraph 
   26     A factor is a part of a linear constraint corresponding either a cost ||A x - b|| or 
   28     In both cases, we have Ax = sum A_i x_i, where some A_i are null. One object of 
   29     class Factor stores one of the A_i, along with the correspond <i> index. It is 
   30     simply a pair (index, matrix). 
   32     This class is used as a arguments of some of the setup functions of FactorGraph. 
   42     The class FactorGraph stores a block-sparse linear-constrained quadratic program 
   43     (LCQP) of variable x=(x1...xn). The size of the problem is set up at construction of 
   45     Methods add_factor() and add_factor_constraint() are used to set up the problem. 
   46     Method solve() is used to compute the solution to the problem. 
   51         Initialize a QP sparse problem as min || A x - b || so that C x = d 
   52         where  x = (x1, .., xn), and dim(xi) = variableSize and n = nbVariables 
   53         After construction, A, b, C and d are allocated and set to 0. 
   55         self.
nx = variableSize
 
   64         Internal function: not designed to be called by the user. 
   65         Create a factor matrix [ A1 0 A2 0 A3 ... ] where the Ai's are placed at 
   66         the indexes of the factors. 
   68         assert len(factors) > 0
 
   69         nr = factors[0].matrix.shape[0]  
 
   74         for factor 
in factors:
 
   75             assert factor.matrix.shape == (nr, self.
nx)
 
   76             A[:, self.
nx * factor.index : self.
nx * (factor.index + 1)] = factor.matrix
 
   81         Add a factor || sum_{i} factor[i].matrix * x_{factor[i].index} - reference || 
   86         self.
b = np.vstack([self.
b, reference])
 
   90         Add a factor sum_{i} factor[i].matrix * x_{factor[i].index} =  reference 
   95         self.
d = np.vstack([self.
d, reference])
 
   99         Implement a LCQP solver, with numerical threshold eps. 
  101         Cp = npl.pinv(self.
C, eps)
 
  103         P = 
eye(self.
nx * self.
N) - Cp * self.
C 
  104         xopt += npl.pinv(self.
A * P, eps) * (self.
b - self.
A * xopt)