iCub-main
algorithms.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 iCub Facility - Istituto Italiano di Tecnologia
3  * Author: Ugo Pattacini
4  * email: ugo.pattacini@iit.it
5  * Permission is granted to copy, distribute, and/or modify this program
6  * under the terms of the GNU General Public License, version 2 or any
7  * later version published by the Free Software Foundation.
8  *
9  * A copy of the license can be found at
10  * http://www.robotcub.org/icub/license/gpl.txt
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details
16 */
17 
18 #include <yarp/math/Math.h>
19 #include <yarp/math/SVD.h>
21 
22 using namespace std;
23 using namespace yarp::sig;
24 using namespace yarp::math;
25 using namespace iCub::optimization;
26 
27 
28 /****************************************************************/
29 bool iCub::optimization::minVolumeEllipsoid(const deque<Vector> &points,
30  const double tol,
31  Matrix &A, Vector &c)
32 {
33  // This code is a C++ version of the MATLAB script written by:
34  // Nima Moshtagh (nima@seas.upenn.edu), University of Pennsylvania
35  //
36  // It makes use of the Khachiyan algorithm and aims at minimizing
37  // iteratively the following problem:
38  //
39  // min log(det(A))
40  // s.t. (points[i]-c)'*A*(points[i]-c)<=1
41 
42  if (points.empty())
43  return false;
44 
45  // initialization
46  int d=(int)points.front().length();
47  int N=(int)points.size();
48  Vector u(N,1.0/N);
49  Matrix U(N,N); U.diagonal(u);
50  Matrix Q(d+1,N);
51  for (int row=0; row<Q.rows(); row++)
52  for (int col=0; col<Q.cols(); col++)
53  Q(row,col)=points[col][row];
54  for (int col=0; col<Q.cols(); col++)
55  Q(Q.rows()-1,col)=1.0;
56  Matrix Qt=Q.transposed();
57 
58  // run the Khachiyan algorithm
59  Matrix M;
60  while (true)
61  {
62  M=Qt*pinv(Q*U*Qt)*Q;
63  int j=0; double max=M(j,j);
64  for (int row=1; row<M.rows(); row++)
65  {
66  if (M(row,row)>max)
67  {
68  max=M(row,row);
69  j=row;
70  }
71  }
72  double step_size=(max-d-1.0)/((d+1.0)*(max-1.0));
73  Vector new_u=(1.0-step_size)*u;
74  new_u[j]+=step_size;
75  if (norm(new_u-u)<tol)
76  break;
77  u=new_u;
78  U.diagonal(u);
79  }
80 
81  // compute the ellipsoid parameters
82  Matrix P=Q.removeRows(Q.rows()-1,1);
83  c=P*u;
84  Matrix C(c.length(),c.length());
85  for (int col=0; col<C.cols(); col++)
86  C.setCol(col,c[col]*c);
87  A=(1.0/d)*pinv(P*U*P.transposed()-C);
88 
89  return true;
90 }
91 
92 
bool minVolumeEllipsoid(const std::deque< yarp::sig::Vector > &points, const double tol, yarp::sig::Matrix &A, yarp::sig::Vector &c)
Find the minimum volume ellipsoide (MVEE) of a set of N d-dimensional data points.
double norm(const yarp::sig::Matrix &M, int col)
Returns the norm of the vector given in the form: matrix(:,col).
const FSC max
Definition: strain.h:48
A
Definition: sine.m:16