Xmipp  v3.23.11-Nereus
Classes | Functions
linear_system_helper.h File Reference
#include "matrix1d.h"
#include "matrix2d.h"
Include dependency graph for linear_system_helper.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

class  PseudoInverseHelper
 
class  WeightedLeastSquaresHelper
 
class  WeightedLeastSquaresHelperMany
 

Functions

void solveLinearSystem (PseudoInverseHelper &h, Matrix1D< double > &result)
 
void solveLinearSystem (WeightedLeastSquaresHelperMany &h, std::vector< Matrix1D< double >> &result)
 
void weightedLeastSquares (WeightedLeastSquaresHelper &h, Matrix1D< double > &result)
 
void weightedLeastSquares (WeightedLeastSquaresHelperMany &h, std::vector< Matrix1D< double >> &results)
 
void ransacWeightedLeastSquares (WeightedLeastSquaresHelper &h, Matrix1D< double > &result, double tol, int Niter=10000, double outlierFraction=0.25, int Nthreads=1)
 

Function Documentation

◆ ransacWeightedLeastSquares()

void ransacWeightedLeastSquares ( WeightedLeastSquaresHelper h,
Matrix1D< double > &  result,
double  tol,
int  Niter = 10000,
double  outlierFraction = 0.25,
int  Nthreads = 1 
)

Solve Weighted least square problem Ax=b and weights w, with RANSAC. Tol is a tolerance value: if an equation is fulfilled with an error smaller than tol, then it is considered to fulfill the model. Niter is the number of RANSAC iterations to perform. The outlier fraction is the fraction of equations that, at maximum, can be considered as outliers.

Definition at line 332 of file linear_system_helper.cpp.

334 {
335  // Read and preprocess the images
336  pthread_t * th_ids = new pthread_t[Nthreads];
337  ThreadRansacArgs * th_args = new ThreadRansacArgs[Nthreads];
338  for (int nt = 0; nt < Nthreads; nt++) {
339  // Passing parameters to each thread
340  th_args[nt].myThreadID = nt;
341  th_args[nt].h = &h;
342  th_args[nt].tol = tol;
343  th_args[nt].Niter = Niter/Nthreads;
344  th_args[nt].outlierFraction = outlierFraction;
345  pthread_create((th_ids + nt), NULL, threadRansacWeightedLeastSquares,
346  (void *) (th_args + nt));
347  }
348 
349  // Waiting for threads to finish
350  double err=1e38;
351  for (int nt = 0; nt < Nthreads; nt++)
352  {
353  pthread_join(*(th_ids + nt), NULL);
354  if (th_args[nt].error<err)
355  {
356  err=th_args[nt].error;
357  result=th_args[nt].result;
358  }
359  }
360 
361  // Threads structures are not needed any more
362  delete []th_ids;
363  delete []th_args;
364 }
Matrix1D< double > result
WeightedLeastSquaresHelper * h
void * threadRansacWeightedLeastSquares(void *args)

◆ solveLinearSystem() [1/2]

void solveLinearSystem ( PseudoInverseHelper h,
Matrix1D< double > &  result 
)

Solve Linear system Ax=b with pseudoinverse. A and b must be set inside the PseudoInverseHelper, the rest of the fields in PseudoInverseHelper are used by this routine to avoid several allocation/deallocations DEPRECATED, use solveLinearSystem(WeightedLeastSquaresHelperMany &h, std::vector<Matrix1D<double>> &results)

Definition at line 33 of file linear_system_helper.cpp.

34 {
35  Matrix2D<double> &A=h.A;
36  Matrix1D<double> &b=h.b;
37  Matrix2D<double> &AtA=h.AtA;
38  Matrix2D<double> &AtAinv=h.AtAinv;
39  Matrix1D<double> &Atb=h.Atb;
40 
41  // Compute AtA and Atb
42  int I=MAT_YSIZE(A);
43  int J=MAT_XSIZE(A);
44  AtA.initZeros(J,J);
45  Atb.initZeros(J);
46  for (int i=0; i<J; ++i)
47  {
48  for (int j=0; j<J; ++j)
49  {
50  double AtA_ij=0;
51  for (int k=0; k<I; ++k)
52  AtA_ij+=MAT_ELEM(A,k,i)*MAT_ELEM(A,k,j);
53  MAT_ELEM(AtA,i,j)=AtA_ij;
54  }
55  double Atb_i=0;
56  for (int k=0; k<I; ++k)
57  Atb_i+=MAT_ELEM(A,k,i)*VEC_ELEM(b,k);
58  VEC_ELEM(Atb,i)=Atb_i;
59  }
60 
61  // Compute the inverse of AtA
62  AtA.inv(AtAinv);
63 
64  // Now multiply by Atb
65  result.initZeros(J);
67  VEC_ELEM(result,i)+=MAT_ELEM(AtAinv,i,j)*VEC_ELEM(Atb,j);
68 }
#define FOR_ALL_ELEMENTS_IN_MATRIX2D(m)
Definition: matrix2d.h:104
#define MAT_YSIZE(m)
Definition: matrix2d.h:124
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
Matrix2D< double > AtAinv
Matrix1D< double > Atb
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
doublereal * b
Matrix1D< double > b
Matrix2D< double > A
void initZeros()
Definition: matrix1d.h:592
#define j
Matrix2D< double > AtA
#define MAT_XSIZE(m)
Definition: matrix2d.h:120
void initZeros()
Definition: matrix2d.h:626

◆ solveLinearSystem() [2/2]

void solveLinearSystem ( WeightedLeastSquaresHelperMany h,
std::vector< Matrix1D< double >> &  result 
)

Solve Linear system Ax=[b] with pseudoinverse. A and all 'b's must be set inside the helper

Definition at line 70 of file linear_system_helper.cpp.

71 {
72  const size_t sizeI = h.A.mdimy;
73  const size_t sizeJ = h.A.mdimx;
74  h.AtA.resizeNoCopy(sizeJ, sizeJ);
75  h.Atb.resizeNoCopy(sizeJ);
76  // compute AtA
77  h.At = h.A.transpose();
78  // for each row of the output
79  for (size_t i = 0; i < sizeJ; ++i)
80  {
81  // for each column of the output (notice that we read row-wise from At)
82  for (size_t j = i; j < sizeJ; ++j)
83  {
84  double AtA_ij = 0;
85  // multiply elementwise row by row from At
86  for (size_t k = 0; k < sizeI; ++k) {
87  AtA_ij += h.At.mdata[i * sizeI + k] * h.At.mdata[j * sizeI + k];
88  }
89  // AtA is symmetric, so we don't need to iterate over everything
90  h.AtA.mdata[i * sizeJ + j] = h.AtA.mdata[j * sizeJ + i] = AtA_ij;
91  }
92  }
93  // Compute the inverse of AtA
94  h.AtA.inv(h.AtAinv); // AtAinv is also square matrix, same size as AtA
95 
96  assert(results.size() == h.bs.size());
97  auto res_it = results.begin();
98  auto b_it = h.bs.begin();
99  for (; res_it != results.end(); ++res_it, ++b_it) {
100  for (size_t i = 0; i < sizeJ; ++i)
101  {
102  double Atb_i = 0;
103  for (size_t k = 0; k < sizeI; ++k) {
104  Atb_i += h.A.mdata[k * sizeJ + i] * b_it->vdata[k];
105  }
106  h.Atb.vdata[i] = Atb_i;
107  }
108  // Now multiply by Atb
109  res_it->initZeros(sizeJ);
110  for (size_t i = 0; i < sizeJ; i++) {
111  for (size_t j = 0; j < sizeJ; j++) {
112  res_it->vdata[i] += h.AtAinv.mdata[i * sizeJ +j] * h.Atb.vdata[j];
113  }
114  }
115  }
116 }
void inv(Matrix2D< T > &result) const
Definition: matrix2d.cpp:663
T * mdata
Definition: matrix2d.h:395
Matrix2D< T > transpose() const
Definition: matrix2d.cpp:1314
std::vector< Matrix1D< double > > bs
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
void resizeNoCopy(int Ydim, int Xdim)
Definition: matrix2d.h:534
size_t mdimy
Definition: matrix2d.h:413
#define j
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
size_t mdimx
Definition: matrix2d.h:410
T * vdata
The array itself.
Definition: matrix1d.h:258

◆ weightedLeastSquares() [1/2]

void weightedLeastSquares ( WeightedLeastSquaresHelper h,
Matrix1D< double > &  result 
)

Solve Weighted least square problem Ax=b with pseudoinverse and weights w. A, w and b must be set inside the WeightedLeastSquaresHelper, the rest of the fields in WeightedLeastSquaresHelper are used by this routine to avoid several allocation/deallocations.

The normal equations of this problem are A^t W A x = A^t W b, where W is a diagonal matrix whose entries are in the vector w.

DEPRECATED, use weightedLeastSquares(WeightedLeastSquaresHelperMany &h, std::vector<Matrix1D<double>> &results)

Definition at line 119 of file linear_system_helper.cpp.

120 {
121  Matrix2D<double> &A=h.A;
122  Matrix1D<double> &b=h.b;
123  Matrix1D<double> &w=h.w;
124 
125  // See http://en.wikipedia.org/wiki/Least_squares#Weighted_least_squares
127  {
128  double wii=sqrt(VEC_ELEM(w,i));
129  VEC_ELEM(b,i)*=wii;
130  for (size_t j=0; j<MAT_XSIZE(A); ++j)
131  MAT_ELEM(A,i,j)*=wii;
132  }
133  solveLinearSystem(h,result);
134 }
#define VEC_ELEM(v, i)
Definition: matrix1d.h:245
void sqrt(Image< double > &op)
doublereal * w
#define i
#define MAT_ELEM(m, i, j)
Definition: matrix2d.h:116
#define FOR_ALL_ELEMENTS_IN_MATRIX1D(v)
Definition: matrix1d.h:72
doublereal * b
Matrix1D< double > b
Matrix2D< double > A
void solveLinearSystem(PseudoInverseHelper &h, Matrix1D< double > &result)
#define j
#define MAT_XSIZE(m)
Definition: matrix2d.h:120

◆ weightedLeastSquares() [2/2]

void weightedLeastSquares ( WeightedLeastSquaresHelperMany h,
std::vector< Matrix1D< double >> &  results 
)

Solve Weighted least square problem Ax=b with pseudoinverse and weights w for multiple b. A, w and all 'b's must be set inside the helper to avoid several allocation/deallocations.

The normal equations of this problem are A^t W A x = A^t W b, where W is a diagonal matrix whose entries are in the vector w.

Definition at line 136 of file linear_system_helper.cpp.

137 {
138  const size_t sizeW = h.w.vdim;
139  h.w_sqrt.resizeNoCopy(h.w);
140  // compute weights
141  for(size_t i = 0; i < sizeW; ++i) {
142  h.w_sqrt.vdata[i] = sqrt(h.w.vdata[i]);
143  }
144  // update the matrix
145  const size_t sizeX = h.A.mdimx;
146  for(size_t i = 0; i < sizeW; ++i) {
147  const size_t offset = i * sizeX;
148  const auto v = h.w_sqrt[i];
149  for (size_t j = 0; j < sizeX; ++j)
150  h.A.mdata[offset + j] *= v;
151  }
152  // update values
153  for (auto &b : h.bs) {
154  for(size_t i = 0; i < sizeW; ++i) {
155  b.vdata[i] *= h.w_sqrt[i];
156  }
157  }
158  solveLinearSystem(h, results);
159 }
void sqrt(Image< double > &op)
T * mdata
Definition: matrix2d.h:395
std::vector< Matrix1D< double > > bs
#define i
doublereal * b
void solveLinearSystem(PseudoInverseHelper &h, Matrix1D< double > &result)
#define j
void resizeNoCopy(int Xdim)
Definition: matrix1d.h:458
size_t mdimx
Definition: matrix2d.h:410
T * vdata
The array itself.
Definition: matrix1d.h:258
size_t vdim
Number of elements.
Definition: matrix1d.h:264