a

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
Jagang
Date:
Sun Dec 14 17:49:01 2014 +0000
Commit message:
New

Changed in this revision

KalmanFilter/EKF.h Show annotated file Show diff for this revision Revisions of this file
KalmanFilter/EKF_obsolete.h Show annotated file Show diff for this revision Revisions of this file
KalmanFilter/Mat.h Show annotated file Show diff for this revision Revisions of this file
LinkedList/LinkedList.cpp Show annotated file Show diff for this revision Revisions of this file
LinkedList/LinkedList.h Show annotated file Show diff for this revision Revisions of this file
LogUtil/LogUtil.cpp Show annotated file Show diff for this revision Revisions of this file
LogUtil/LogUtil.h Show annotated file Show diff for this revision Revisions of this file
Map/Map.cpp Show annotated file Show diff for this revision Revisions of this file
Map/Map.h Show annotated file Show diff for this revision Revisions of this file
Map/Obstacle/Obs_circle.cpp Show annotated file Show diff for this revision Revisions of this file
Map/Obstacle/Obs_circle.h Show annotated file Show diff for this revision Revisions of this file
Map/Obstacle/Obstacle.cpp Show annotated file Show diff for this revision Revisions of this file
Map/Obstacle/Obstacle.h Show annotated file Show diff for this revision Revisions of this file
Odometry/Odometry.cpp Show annotated file Show diff for this revision Revisions of this file
Odometry/Odometry.h Show annotated file Show diff for this revision Revisions of this file
QEI/QEI.cpp Show annotated file Show diff for this revision Revisions of this file
QEI/QEI.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KalmanFilter/EKF.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,638 @@
+#include "Mat.h"
+
+ 
+template<typename T>
+Mat<T> PIDCONTROL( Mat<T> phi_d, Mat<T> u_p, Mat<T> e_old, T dt, int behaviour = 3)
+{
+    Mat<T> r(phi_d-u_p);
+    e_old = e_old + r;
+
+    /*PID ANGULAR ROTATION : PERFECT*/
+    Mat<T> Kp((T) -0.01, 2,1);
+    Mat<T> Ki((T)50, 2,1);
+    Mat<T> Kd((T)0, 2,1);
+    /*-------------------------------*/
+    
+    if(behaviour==2)
+    {
+        phi_d.afficher();
+        Kp = (T)10000*Kp;
+        Ki = ((T)10000)*Ki;
+        Kd = Mat<T>((T)1,2,1);
+        Kd = ((T)0)*Kd;
+    
+    }
+    
+    r = Kp%r + dt*Ki%e_old + ((double)1.0/dt)*Kd%r;
+        
+    return r;
+}
+
+
+template<typename T>
+class EKF
+{
+    private :
+    
+    Serial *pcs;
+    T time;
+    T dt;   /* par default : = 0.005 */
+    int nbr_state;
+    int nbr_ctrl;
+    int nbr_obs;
+    
+    Mat<T> dX;  /*desired state*/
+    Mat<T>* _X; /*previous state*/
+    Mat<T>* X;      /*states*/
+    Mat<T>* X_; /*derivated states or next states... (continuous/discrete)*/
+    Mat<T>* u;      /*controls*/
+    Mat<T>* z;      /*observations/measurements*/
+    Mat<T> obs_old;
+    Mat<T> e_old;
+    
+    Mat<T>* Ki;
+    Mat<T>* Kp;
+    Mat<T>* Kd;
+    Mat<T>* Kdd;    
+    
+    Mat<T>* A;      /*linear relation matrix between states and derivated states.*/
+    /*par default : X_ = A * X + B * u / x_i = x_i + dt * x_i_ + b_i * u_i... */
+    Mat<T>* B;      /*linear relation matrix between derivated states and control.*/
+    /*par default : B = 1 */
+    Mat<T>* C;      /*linear relation matrix between states and observation.*/
+    /*par default : C = [1 0], on observe les positions, non leurs dérivées. */
+
+    /*Noise*/
+    T std_noise;    /*par defaut : 0.0005*/
+    Mat<T>* Sigma;  /*covariance matrix*/
+    Mat<T>* Q;      /*process noise*/
+    Mat<T>* R;      /*measurement noise*/
+    
+    /*Prediction*/
+    Mat<T> K;       // Kalman Gain...
+    Mat<T> Sigma_p;
+    
+    /*Others*/
+    bool filterOn;
+    Mat<T>* Identity;
+    
+    
+    /*Extended*/
+    bool extended;
+    Mat<T> (*ptrMotion)(Mat<T> state, Mat<T> command, T dt);
+    Mat<T> (*ptrSensor)(Mat<T> state, Mat<T> command, Mat<T> d_state, T dt);
+    Mat<T> G;
+    Mat<T> H;
+    Mat<T> (*ptrJMotion)(Mat<T> state, Mat<T> command, T dt);
+    Mat<T> (*ptrJSensor)(Mat<T> state, Mat<T> command, Mat<T> d_state, T dt);
+    
+    
+    public :
+    
+    EKF(Serial *pc, int nbr_state_, int nbr_ctrl_, int nbr_obs_, T dt_, T std_noise_, Mat<T> currentState, bool ext = false, bool filterOn = true)
+    {
+        this->filterOn = filterOn;
+        this->pcs = pc;
+        /*extension*/
+        time = (T)0;
+        extended = ext;
+        ptrMotion = NULL;
+        ptrSensor = NULL;
+        ptrJMotion = NULL;
+        ptrJSensor = NULL;
+        G = Mat<T>((T)0, nbr_state_, nbr_state_);
+        H = Mat<T>((T)0, nbr_obs_, nbr_state_);
+        
+        /*----------------*/
+        
+        dt = dt_;
+        nbr_state = nbr_state_;
+        nbr_ctrl = nbr_ctrl_;
+        nbr_obs = nbr_obs_;
+        
+        _X = new Mat<T>((T)0, nbr_state, (int)1);       /*previous state*/
+        X = new Mat<T>(currentState);                   /*states*/
+        X_ = new Mat<T>((T)0, nbr_state, (int)1);       /*derivated states*/
+        u = new Mat<T>((T)0, nbr_ctrl, (int)1);         /*controls*/
+        z = new Mat<T>((T)0, nbr_obs, (int)1);  
+        obs_old = *z;                       /*observations*/
+        e_old = *z;
+        A = new Mat<T>((T)0, nbr_state, nbr_state);     /*linear relation or jacobian matrix between states and derivated states.*/
+        B = new Mat<T>((T)0, nbr_state, nbr_ctrl);      /*linear relation matrix between derivated states and control.*/
+        C = new Mat<T>((T)0, nbr_obs, nbr_state);       /*linear relation or jacobian matrix between states and observation.*/
+    
+        Ki = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+        Kp = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+        Kd = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+        Kdd = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+    
+    
+        std_noise = std_noise_;
+        Sigma = new Mat<T>((T)0, nbr_state, nbr_state);
+        Q = new Mat<T>((T)0, nbr_state, nbr_state);
+        R = new Mat<T>((T)0, nbr_obs, nbr_obs/*1*/);
+    
+        /*Initialize Covariance matrix as the identity matrix.*/
+        for(int i=1;i<=nbr_state;i++)
+        {
+            Sigma->set((T)1, i,i);
+            R->set( (T)1, i,i);
+            /*
+            for(int j=1;j<=nbr_state;j++)
+            {
+                Sigma->set((T)1, i, j);
+            
+                //if(i<=nbr_obs && j==1)
+                //  R->set(std_noise*std_noise, i, j);
+                
+            }
+            */
+        }
+    
+        Identity = new Mat<T>(*Sigma);
+        *Q = (std_noise*std_noise)*(*Identity);
+        *R = (std_noise*std_noise)*(*R);
+    
+    }
+
+    ~EKF()
+    {
+        delete _X;
+        delete X;
+        delete X_;
+        delete u;
+        delete z;
+        delete A;
+        delete B;
+        delete C;
+    
+        delete Ki;
+        delete Kp;
+        delete Kd;
+        delete Kdd;
+    
+        delete Sigma;
+        delete Q;
+        delete R;
+    
+        delete Identity;
+    }
+
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+
+
+    int initA( Mat<T> A_)
+    {
+        if(A_ == *Identity)
+        {
+            for(int i=1;i<=(int)(nbr_state/2);i++)
+            {
+                A->set( dt, i, i+(int)(nbr_state/2));
+            }
+        
+            return 1;
+        }
+        else
+        {
+            if(A_.getColumn() == nbr_state && A_.getLine() == nbr_state)
+            {
+                *A = A_;
+                return 1;
+            }
+            else
+            {
+                cout << "ERREUR : mauvais format de matrice d'initialisation de A." << endl;
+                return 0;
+            }
+        }
+    }
+
+
+    int initB( Mat<T> B_)
+    {   
+        if(B_.getColumn() == nbr_ctrl && B_.getLine() == nbr_state)
+        {
+            *B = B_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de matrice d'initialisation de B." << endl;
+            return 0;
+        }
+    
+    }
+    
+    
+    
+    int initC( Mat<T> C_)
+    {   
+        if(C_.getColumn() == nbr_state && C_.getLine() == nbr_obs)
+        {
+            *C = C_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de matrice d'initialisation de C." << endl;
+            return 0;
+        }
+    
+    }
+    
+    /*extension*/
+    void initMotion( Mat<T> motion(Mat<T>, Mat<T>, T) )
+    {
+        ptrMotion = motion;
+    }
+    
+    
+    
+    void initSensor( Mat<T> sensor(Mat<T>, Mat<T>, Mat<T>, T) )
+    {   
+        ptrSensor = sensor; 
+    }
+    
+    void initJMotion( Mat<T> jmotion(Mat<T>, Mat<T>, T) )
+    {
+        ptrJMotion = jmotion;
+    }
+    
+    
+    
+    void initJSensor( Mat<T> jsensor(Mat<T>, Mat<T>, Mat<T>, T) )
+    {   
+        ptrJSensor = jsensor;   
+    }
+    
+    
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+
+
+    int setKi( Mat<T> Ki_)
+    {
+        if(Ki_.getColumn() == nbr_state && Ki_.getLine() == nbr_ctrl)
+        {
+            *Ki = Ki_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Ki." << endl;
+            return 0;
+        }
+    }
+    
+    int setKp( Mat<T> Kp_)
+    {
+        if(Kp_.getColumn() == nbr_state && Kp_.getLine() == nbr_ctrl)
+        {
+            *Kp = Kp_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Kp." << endl;
+            return 0;
+        }
+    }
+    
+    
+    
+    int setKd( Mat<T> Kd_)
+    {
+        if(Kd_.getColumn() == nbr_state && Kd_.getLine() == nbr_ctrl)
+        {
+            *Kd = Kd_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Kd." << endl;
+            return 0;
+        }
+
+    }
+    
+    int setKdd( Mat<T> Kdd_)
+    {
+        if(Kdd_.getColumn() == nbr_state && Kdd_.getLine() == nbr_ctrl)
+        {
+            *Kdd = Kdd_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Kdd." << endl;
+            return 0;
+        }
+
+    }
+    
+    
+    void setdt( float dt_)
+    {
+        dt = dt_;
+    }
+    
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/   
+    
+    
+    Mat<T> getCommand()
+    {
+        return *u;
+    }   
+    
+    Mat<T> getX()
+    {
+        return *X;
+    }
+
+    Mat<T> getSigma()
+    {
+        return *Sigma;
+    }   
+
+
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/       
+    
+    
+    Mat<T> predictState()       /*return the computed predicted state*/
+    {
+        return (!extended ? (*A)*(*X)+(*B)*(*u) : ptrMotion(*X, *u, dt) );
+    }
+    
+    
+    Mat<T> predictCovariance()  /*return the predicted covariance matrix.*/
+    {        
+        
+        if(extended)
+            G = ptrJMotion(*X, *u, dt);
+                    
+            
+        return (filterOn ? ( (!extended ? ((*A)*(*Sigma))* transpose(*A) : G*(*Sigma)*transpose(G) ) + *Q) : *Identity);
+    }
+    
+        
+    Mat<T> calculateKalmanGain()    /*return the Kalman Gain K = C*Sigma_p * (C*Sigma_p*C.T +R).inv */
+    {       
+        
+        Sigma_p = predictCovariance();  
+                
+        if(extended)
+            H = ptrJSensor(*X, *u, dX,dt);
+                
+
+        if(!extended)                    
+            return (filterOn ? Sigma_p * transpose(*C) * invGJ( (*C) * Sigma_p * transpose(*C) + *R) : *Identity);
+        else
+        {
+            pcm.printf("Sigma\n");
+            Sigma_p.afficherM();
+            Mat<double> test( H * Sigma_p * transpose(H) + *R);            
+            test = invGJ(test);            
+            pcm.printf("test inverse\n");            
+                     
+            return (filterOn ? Sigma_p * transpose(H) * test : *Identity);        
+        }
+    }
+    
+        
+    Mat<T> correctState()       /*update X */
+    {
+        Mat<T> X_p( predictState());        
+    
+        *_X = *X;
+        
+        if(filterOn)
+            *X = X_p + K*( (*z) - (!extended ? (*C)*X_p  : ptrSensor(X_p, *u, dX, dt) ) );
+        else
+            *X = X_p;
+    
+        return *X;
+    }
+    
+        
+    Mat<T> correctCovariance()  /*update Sigma*/
+    {
+        *Sigma = (filterOn ? (*Identity - K* (!extended ? (*C) : H) ) *Sigma_p : *Identity);
+    
+        return *Sigma;
+    }
+    
+    
+    void state_Callback()       /* Update all... */
+    {            
+        time += dt;
+        
+        if( extended && (ptrMotion == NULL || ptrSensor == NULL || ptrJMotion == NULL || ptrJSensor == NULL) )
+        {
+            //~EKF();
+            throw("ERREUR : les fonctions ne sont pas initialisées...");
+        }       
+        
+        K = calculateKalmanGain();              
+        correctState();                
+        correctCovariance();        
+    }
+    
+    void measurement_Callback(Mat<T> measurements, Mat<T> dX_, bool measure = false)
+    {
+        if( extended && (ptrMotion == NULL || ptrSensor == NULL || ptrJMotion == NULL || ptrJSensor == NULL) )
+        {
+            //~EKF();
+            throw("ERREUR : les fonctions ne sont pas initialisées...");
+        }
+        
+        dX = dX_;
+        
+        *z = (!extended || measure ? measurements : ptrSensor(*X,*u, dX, dt) ); 
+    }
+    
+    void measurement_Callback(Mat<T> measurements)
+    {
+        if( extended && (ptrMotion == NULL || ptrSensor == NULL || ptrJMotion == NULL || ptrJSensor == NULL) )
+        {
+            //~EKF();
+            throw("ERREUR : les fonctions ne sont pas initialisées...");
+        }
+        
+        
+        *z = (!extended ? measurements : ptrSensor(*X,*u, dX, dt) );    
+    }
+    
+    
+    void computeCommand( Mat<T> desiredX, T dt_, int mode)
+    {
+        obs_old = obs_old + dt_*(*z);
+        
+        /*work on observation instead of state vector ???? */
+        
+        
+        if(dt_ != (T)0 && mode != -1)
+        {
+            *u = (*Kp)*(desiredX - (*X));
+            if(mode >= 1)
+                *u = *u + (T)(dt_)*(*Ki)*(desiredX - (*X));
+            if(mode >= 2)
+                *u = *u + (T)((double)1.0/dt_)*(*Kd)*(desiredX - (*X));
+            if(mode >= 3)
+                *u = *u + (T)((double)1.0/(dt_*dt_))*(*Kdd)*(desiredX - (*X));                      
+        }       
+        else if(mode !=-1)
+        {
+            *u = (*Kp)*(desiredX - (*X));       
+        }
+            
+        if(mode == -1)
+        {
+        
+            Mat<T> bicycle((T)0, 3,1);
+                        bicycle.set((T)100, 1,1);  /*radius*/
+                bicycle.set((T)100, 2,1);
+                bicycle.set((T)66, 3,1);   /*entre-roue*/
+                
+            T rho = (T)sqrt(z->get(1,1)*z->get(1,1) + z->get(2,1)*z->get(2,1));
+            T alpha = atan21( dX.get(2,1)-X->get(2,1), dX.get(1,1) - X->get(1,1) );
+            T beta = alpha + X->get(3,1) + dX.get(3,1);
+            
+            cout << "alpha = " << alpha << endl;
+            cout << "rho = " << rho << endl;
+            cout << "beta = " << beta << endl;          
+            
+            T krho = (double)(rho > 1 ? rho : 0.1);
+            T kalpha = (double)rho*10;
+            T kbeta = (double)2*beta/(rho+1);
+            //T krho = 1;
+            //T kbeta = 1;
+            //T kalpha = 1-5.0/3.0*kbeta+2.0/PI*krho*rho;
+            
+            if(alpha >= 0.2 || alpha <= -0.2)
+            {
+                krho = krho/100;
+                kbeta = kbeta/100;
+                //kalpha = kalpha*alpha;
+            }       
+            else if(rho >=1 )
+            {
+                kalpha = kalpha/100;
+                kbeta = kbeta/100;
+                krho = krho*(rho-1);
+            }           
+            else 
+            {
+                kbeta = kbeta*beta;
+                kalpha = 0;
+                krho = krho/100;
+            }       
+                        
+            T vd = krho*rho;
+            T wd = kalpha*alpha +  kbeta*beta;
+            
+            
+            u->set( vd, 1,1);
+            u->set( wd, 2,1);       
+            
+        }
+        
+        if(mode == -2)
+        {
+            T r = (T)100;  /*radius*/
+                T l = (T)66;   /*entre-roue*/
+                T phi_max = 200;
+                
+            T rho = (T)sqrt((dX.get(1,1)-X->get(1,1))*(dX.get(1,1)-X->get(1,1)) + (dX.get(2,1)-X->get(2,1))*(dX.get(2,1)-X->get(2,1)));
+            T alpha = atan21( dX.get(2,1)-X->get(2,1), dX.get(1,1) - X->get(1,1) ) - atan21(sin(X->get(3,1)), cos(X->get(3,1)));
+            alpha = atan21( sin(alpha), cos(alpha));
+            T beta = -X->get(3,1) + dX.get(3,1);
+            beta = atan21(sin(beta), cos(beta));
+            
+            cout << "alpha = " << alpha << endl;
+            cout << "rho = " << rho << endl;
+            cout << "beta = " << beta << endl;          
+            
+            //T krho = (double)(rho > 1 ? rho : 0.1);
+            //T kalpha = (double)rho*10;
+            //T kbeta = (double)2*beta/(rho+1);
+            T krho = 1;
+            T kbeta = 0.2;
+            T kalpha = 1-5.0/3.0*kbeta+2.0/PI*krho*rho;
+            int behaviour = 0;
+            
+            cout << "test : " << ( fabs_(alpha) >= 0.1 && (( (dX.get(1,1)+1 <= X->get(1,1)) || (dX.get(1,1)-1 >= X->get(1,1)) ) || ( (dX.get(2,1)+1 <= X->get(2,1)) || (dX.get(2,1)-1 >= X->get(2,1)) ) )) << endl;
+            
+            if( fabs_(alpha) >= 0.1 && ( ( (dX.get(1,1)+1 <= X->get(1,1)) || (dX.get(1,1)-1 >= X->get(1,1)) ) || ( (dX.get(2,1)+1 <= X->get(2,1)) || (dX.get(2,1)-1 >= X->get(2,1)) ) ) )
+            {
+                krho = krho/1000;
+                kalpha = kbeta/10;
+                kbeta = 0;
+                behaviour = 1;
+            }       
+            else if(rho >=0.1 )
+            {
+                kalpha = kalpha/10000;
+                kbeta = 0;
+                krho = krho;
+                behaviour = 2;
+            }           
+            else if(fabs_(beta) >= 0.1) 
+            {
+                kbeta = kbeta*10;
+                kalpha = 0;
+                krho = krho/1000;
+                behaviour = 3;
+            }
+            else
+            {   
+                kbeta = kbeta/100000;
+                kalpha = kalpha/100000;
+                krho = krho/10000;          
+                behaviour = 4;
+            }
+            
+            cout << "behaviour = " << behaviour << endl;
+                        
+            T vd = krho*rho ;
+            T wd = kalpha*alpha +  kbeta*beta;
+            vd = ( fabs_(l/r*vd) <= phi_max ? vd : (vd >= 0 ? r/l*phi_max : -r/l*phi_max) );
+            wd = ( fabs_(l/r*wd) <= phi_max ? wd : (wd >= 0 ? r/l*phi_max : -r/l*phi_max) );    
+            
+            cout << "Vd = " << vd << endl;
+            cout << "Wd = " << wd << endl;
+            cout << "max = " << r/l*phi_max << endl;        
+            
+            T phi_r_d = l/r*(vd/l+wd);
+            T phi_l_d = l/r*(vd/l-wd);
+            
+            
+            Mat<T> phi(2,1);
+            phi.set( phi_r_d, 1,1);
+            phi.set( phi_l_d, 2,1);
+            phi.afficher();
+            
+            Mat<T> phi_p(phi);
+            phi_p.set( u->get(1,1)+u->get(2,1), 1,1);
+            phi_p.set( u->get(1,1)-u->get(2,1), 2,1);
+            phi_p = r/(2*l)*phi_p;
+            
+            if(e_old.getLine() != 2)
+                e_old = (T)0*phi;               
+
+            
+            phi = PIDCONTROL( phi, phi_p, e_old, dt, behaviour);
+            
+            u->set( r/(2*l)*(phi.get(1,1)+phi.get(2,1)), 1,1);
+            u->set( r/(2*l)*(phi.get(1,1)-phi.get(2,1)), 2,1);
+        }
+    }   
+    
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KalmanFilter/EKF_obsolete.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,469 @@
+#include "Mat.h"
+
+template<typename T>
+class EKF
+{
+    private :
+    
+    T dt;   /* par default : = 0.005 */
+    int nbr_state;
+    int nbr_ctrl;
+    int nbr_obs;
+    
+    Mat<T> dX;  /*desired state*/
+    Mat<T>* _X; /*previous state*/
+    Mat<T>* X;      /*states*/
+    Mat<T>* X_; /*derivated states or next states... (continuous/discrete)*/
+    Mat<T>* u;      /*controls*/
+    Mat<T>* z;      /*observations/measurements*/
+    
+    Mat<T>* Ki;
+    Mat<T>* Kp;
+    Mat<T>* Kd;
+    Mat<T>* Kdd;    
+    
+    Mat<T>* A;      /*linear relation matrix between states and derivated states.*/
+    /*par default : X_ = A * X + B * u / x_i = x_i + dt * x_i_ + b_i * u_i... */
+    Mat<T>* B;      /*linear relation matrix between derivated states and control.*/
+    /*par default : B = 1 */
+    Mat<T>* C;      /*linear relation matrix between states and observation.*/
+    /*par default : C = [1 0], on observe les positions, non leurs dérivées. */
+
+    /*Noise*/
+    T std_noise;    /*par defaut : 0.0005*/
+    Mat<T>* Sigma;  /*covariance matrix*/
+    Mat<T>* Q;      /*process noise*/
+    Mat<T>* R;      /*measurement noise*/
+    
+    /*Prediction*/
+    Mat<T> K;       // Kalman Gain...
+    Mat<T> Sigma_p;
+    
+    /*Others*/
+    Mat<T>* Identity;
+    
+    
+    /*Extended*/
+    bool extended;
+    Mat<T> (*ptrMotion)(Mat<T> state, Mat<T> command, T dt);
+    Mat<T> (*ptrSensor)(Mat<T> state, Mat<T> command, Mat<T> d_state, T dt);
+    Mat<T> G;
+    Mat<T> H;
+    Mat<T> (*ptrJMotion)(Mat<T> state, Mat<T> command, T dt);
+    Mat<T> (*ptrJSensor)(Mat<T> state, Mat<T> command, Mat<T> d_state, T dt);
+    
+    
+    public :
+    
+    EKF(int nbr_state_, int nbr_ctrl_, int nbr_obs_, T dt_, T std_noise_, Mat<T> currentState, bool ext = false)
+    {
+        /*extension*/
+        extended = ext;
+        ptrMotion = NULL;
+        ptrSensor = NULL;
+        ptrJMotion = NULL;
+        ptrJSensor = NULL;
+        G = Mat<T>((T)0, nbr_state_, nbr_state_);
+        H = Mat<T>((T)0, nbr_obs_, nbr_state_);
+        
+        /*----------------*/
+        
+        dt = dt_;
+        nbr_state = nbr_state_;
+        nbr_ctrl = nbr_ctrl_;
+        nbr_obs = nbr_obs_;
+        
+        _X = new Mat<T>((T)0, nbr_state, (int)1);       /*previous state*/
+        X = new Mat<T>(currentState);                   /*states*/
+        X_ = new Mat<T>((T)0, nbr_state, (int)1);       /*derivated states*/
+        u = new Mat<T>((T)0, nbr_ctrl, (int)1);         /*controls*/
+        z = new Mat<T>((T)0, nbr_obs, (int)1);          /*observations*/
+        A = new Mat<T>((T)0, nbr_state, nbr_state);     /*linear relation or jacobian matrix between states and derivated states.*/
+        B = new Mat<T>((T)0, nbr_state, nbr_ctrl);      /*linear relation matrix between derivated states and control.*/
+        C = new Mat<T>((T)0, nbr_obs, nbr_state);       /*linear relation or jacobian matrix between states and observation.*/
+    
+        Ki = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+        Kp = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+        Kd = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+        Kdd = new Mat<T>((T)0.08, nbr_ctrl, nbr_state);
+    
+    
+        std_noise = std_noise_;
+        Sigma = new Mat<T>((T)0, nbr_state, nbr_state);
+        Q = new Mat<T>((T)0, nbr_state, nbr_state);
+        R = new Mat<T>((T)0, nbr_obs, nbr_obs/*1*/);
+    
+        /*Initialize Covariance matrix as the identity matrix.*/
+        for(int i=1;i<=nbr_state;i++)
+        {
+            Sigma->set((T)1, i,i);
+            R->set( (T)1, i,i);
+            /*
+            for(int j=1;j<=nbr_state;j++)
+            {
+                Sigma->set((T)1, i, j);
+            
+                //if(i<=nbr_obs && j==1)
+                //  R->set(std_noise*std_noise, i, j);
+                
+            }
+            */
+        }
+    
+        Identity = new Mat<T>(*Sigma);
+        *Q = (std_noise*std_noise)*(*Identity);
+        *R = (std_noise*std_noise)*(*R);
+    
+    }
+
+    ~EKF()
+    {
+        delete _X;
+        delete X;
+        delete X_;
+        delete u;
+        delete z;
+        delete A;
+        delete B;
+        delete C;
+    
+        delete Ki;
+        delete Kp;
+        delete Kd;
+        delete Kdd;
+    
+        delete Sigma;
+        delete Q;
+        delete R;
+    
+        delete Identity;
+    }
+
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+
+
+    int initA( Mat<T> A_)
+    {
+        if(A_ == *Identity)
+        {
+            for(int i=1;i<=(int)(nbr_state/2);i++)
+            {
+                A->set( dt, i, i+(int)(nbr_state/2));
+            }
+        
+            return 1;
+        }
+        else
+        {
+            if(A_.getColumn() == nbr_state && A_.getLine() == nbr_state)
+            {
+                *A = A_;
+                return 1;
+            }
+            else
+            {
+                cout << "ERREUR : mauvais format de matrice d'initialisation de A." << endl;
+                return 0;
+            }
+        }
+    }
+
+
+    int initB( Mat<T> B_)
+    {   
+        if(B_.getColumn() == nbr_ctrl && B_.getLine() == nbr_state)
+        {
+            *B = B_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de matrice d'initialisation de B." << endl;
+            return 0;
+        }
+    
+    }
+    
+    
+    
+    int initC( Mat<T> C_)
+    {   
+        if(C_.getColumn() == nbr_state && C_.getLine() == nbr_obs)
+        {
+            *C = C_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de matrice d'initialisation de C." << endl;
+            return 0;
+        }
+    
+    }
+    
+    /*extension*/
+    void initMotion( Mat<T> motion(Mat<T>, Mat<T>, T) )
+    {
+        ptrMotion = motion;
+    }
+    
+    
+    
+    void initSensor( Mat<T> sensor(Mat<T>, Mat<T>, Mat<T>, T) )
+    {   
+        ptrSensor = sensor; 
+    }
+    
+    void initJMotion( Mat<T> jmotion(Mat<T>, Mat<T>, T) )
+    {
+        ptrJMotion = jmotion;
+    }
+    
+    
+    
+    void initJSensor( Mat<T> jsensor(Mat<T>, Mat<T>, Mat<T>, T) )
+    {   
+        ptrJSensor = jsensor;   
+    }
+    
+    
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+
+
+    int setKi( Mat<T> Ki_)
+    {
+        if(Ki_.getColumn() == nbr_state && Ki_.getLine() == nbr_ctrl)
+        {
+            *Ki = Ki_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Ki." << endl;
+            return 0;
+        }
+    }
+    
+    int setKp( Mat<T> Kp_)
+    {
+        if(Kp_.getColumn() == nbr_state && Kp_.getLine() == nbr_ctrl)
+        {
+            *Kp = Kp_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Kp." << endl;
+            return 0;
+        }
+    }
+    
+    
+    
+    int setKd( Mat<T> Kd_)
+    {
+        if(Kd_.getColumn() == nbr_state && Kd_.getLine() == nbr_ctrl)
+        {
+            *Kd = Kd_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Kd." << endl;
+            return 0;
+        }
+
+    }
+    
+    int setKdd( Mat<T> Kdd_)
+    {
+        if(Kdd_.getColumn() == nbr_state && Kdd_.getLine() == nbr_ctrl)
+        {
+            *Kdd = Kdd_;
+            return 1;
+        }
+        else
+        {
+            cout << "ERREUR : mauvais format de vecteur d'initialisation de Kdd." << endl;
+            return 0;
+        }
+
+    }
+    
+    
+    void setdt( float dt_)
+    {
+        dt = dt_;
+    }
+    
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/   
+    
+    
+    Mat<T> getCommand()
+    {
+        return *u;
+    }   
+    
+    Mat<T> getX()
+    {
+        return *X;
+    }
+
+    Mat<T> getSigma()
+    {
+        return *Sigma;
+    }   
+
+
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/
+/*-------------------------------------------------------------*/       
+    
+    
+    Mat<T> predictState()       /*return the computed predicted state*/
+    {
+        return (!extended ? (*A)*(*X)+(*B)*(*u) : ptrMotion(*X, *u, dt) );
+    }
+    
+    
+    Mat<T> predictCovariance()  /*return the predicted covariance matrix.*/
+    {
+        if(extended)
+            G = ptrJMotion(*X, *u, dt);
+        
+        return ( (!extended ? ((*A)*(*Sigma))* transpose(*A) : G*(*Sigma)*transpose(G) ) + *Q);
+    }
+    
+        
+    Mat<T> calculateKalmanGain()    /*return the Kalman Gain K = C*Sigma_p * (C*Sigma_p*C.T +R).inv */
+    {
+        Sigma_p = predictCovariance();  
+    
+        if(extended)
+            H = ptrJSensor(*X, *u, dX,dt);
+    
+        return ( !extended ? Sigma_p * transpose(*C) * invGJ( (*C) * Sigma_p * transpose(*C) + *R)  : Sigma_p * transpose(H) * invGJ( H * Sigma_p * transpose(H) + *R) );
+    }
+    
+        
+    Mat<T> correctState()       /*update X */
+    {
+        Mat<T> X_p( predictState());        
+    
+        *_X = *X;
+        *X = X_p + K*( (*z) - (!extended ? (*C)*X_p  : ptrSensor(X_p, *u, dX, dt) ) );
+    
+        return *X;
+    }
+    
+        
+    Mat<T> correctCovariance()  /*update Sigma*/
+    {
+        *Sigma = (*Identity - K* (!extended ? (*C) : H) ) *Sigma_p;
+    
+        return *Sigma;
+    }
+    
+    
+    void state_Callback()       /* Update all... */
+    {
+        if( extended && (ptrMotion == NULL || ptrSensor == NULL || ptrJMotion == NULL || ptrJSensor == NULL) )
+        {
+            //~EKF();
+            throw("ERREUR : les fonctions ne sont pas initialisees...");
+        }       
+        
+        K = calculateKalmanGain();          
+        correctState();
+        correctCovariance();
+    }
+    
+    void measurement_Callback(Mat<T> measurements, Mat<T> dX_)
+    {
+        if( extended && (ptrMotion == NULL || ptrSensor == NULL || ptrJMotion == NULL || ptrJSensor == NULL) )
+        {
+            //~EKF();
+            throw("ERREUR : les fonctions ne sont pas initialisees...");
+        }
+        
+        dX = dX_;
+        
+        *z = (!extended ? measurements : ptrSensor(*X,*u, dX, dt) );    
+    }
+    
+    void measurement_Callback(Mat<T> measurements)
+    {
+        if( extended && (ptrMotion == NULL || ptrSensor == NULL || ptrJMotion == NULL || ptrJSensor == NULL) )
+        {
+            //~EKF();
+            throw("ERREUR : les fonctions ne sont pas initialisees...");
+        }
+        
+        
+        *z = (!extended ? measurements : ptrSensor(*X,*u, dX, dt) );    
+    }
+    
+    
+    void computeCommand( Mat<T> desiredX, T dt_, int mode)
+    {
+        if(dt_ != (T)0 && mode != -1)
+        {
+            *u = (*Kp)*(desiredX - (*X));
+            if(mode >= 1)
+                *u = *u + (T)(dt_)*(*Ki)*(desiredX - (*X));
+            if(mode >= 2)
+                *u = *u + (T)((double)1.0/dt_)*(*Kd)*(desiredX - (*X));
+            if(mode >= 3)
+                *u = *u + (T)((double)1.0/(dt_*dt_))*(*Kdd)*(desiredX - (*X));                      
+        }       
+        else if(mode !=-1)
+        {
+            *u = (*Kp)*(desiredX - (*X));       
+        }
+            
+        if(mode <= -1)
+        {
+            
+            Mat<double> bicycle((double)0, 3,1);
+            bicycle.set((double)70, 1,1);  /*radius*/
+            bicycle.set((double)70, 2,1);
+            bicycle.set((double)260, 3,1);   /*entre-roue*/
+            
+            double rho = (double)sqrt(z->get(1,1)*z->get(1,1) + z->get(2,1)*z->get(2,1));
+            double alpha = atan21( dX.get(2,1)-X->get(2,1), dX.get(1,1) - X->get(1,1) );
+            double beta = alpha + X->get(3,1) + dX.get(3,1);
+            
+            cout << "alpha = " << alpha << endl;
+            
+            double krho = (rho > 1 ? rho*3 : 1)/100;
+            double kalpha = rho*300/100;
+            double kbeta = 4*beta/(rho+1)/100;
+            
+            double vd = krho*rho;
+            double wd = kalpha*alpha +  kbeta*beta;
+            
+            double phi_max = 100;
+            
+            double phi_r = bicycle.get(3,1)/bicycle.get(1,1)*(wd+vd/bicycle.get(3,1));
+            double phi_l = bicycle.get(3,1)/bicycle.get(2,1)*(wd+vd/bicycle.get(3,1));
+        
+            phi_r = (phi_r <= phi_max ? phi_r : phi_max);
+            phi_l = (phi_l <= phi_max ? phi_l : phi_max);
+            
+            vd = bicycle.get(1,1)/2*(phi_r+phi_l);
+            wd = bicycle.get(1,1)/(2*bicycle.get(3,1))*(phi_r-phi_l);
+            
+            u->set( vd, 1,1);
+            u->set( wd, 2,1);
+            
+        }
+    }   
+    
+
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/KalmanFilter/Mat.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,4323 @@
+#ifndef MAT_H
+#define MAT_H
+
+#ifndef MBED_DEV
+#include <iostream>
+#endif
+#include <limits>
+#include <cstdlib>
+#include <math.h>
+#include <time.h>
+
+#ifdef OPENCV_USE
+#include <opencv2/opencv.hpp>
+#endif
+#define PI 3.1415926535
+#define maxi 10
+
+using namespace std;
+
+#define throw(message)\
+{cout << "ERROR : " << message << endl << " in file " << __FILE__ << " at line " << __LINE__ << endl;\
+exit(1);}
+
+
+Serial pcm(USBTX, USBRX); // tx, rx
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+class Mat
+{
+    private :
+
+    /*Beware : Mat<T> : [0 ; m_line-1]x[0 ; m_column] */
+        int m_line; /*m_line = length(Mat<T>,1) +1*/
+        int m_column;   /*idem...*/
+        T* mat;
+
+        T det;
+        bool determ;
+        Mat<T>* comm;
+        bool commut;
+        Mat<T>* inv;
+        bool inverse;
+
+        Mat<T>* carre;
+
+
+        /*accuracy*/
+        T epsilon;
+        //T** roundoffmat;
+
+    public :
+
+        Mat();
+        Mat(const Mat<T>& m, bool sq = false);
+        Mat(const Mat<T>& m, T oValue, int d_line, int d_column, int line, int column, bool sq = false); /*initialise les autres valeurs à oValue*/
+        Mat(const Mat<T>& m, int delLine[], int cLine, int delColumn[], int cColumn, bool sq = false);
+        Mat(int line, int column, char mode);
+        Mat( int line, int column);
+        Mat( T value, int line, int column, bool sq = false);
+        void copy(const Mat<T>& m);
+
+        Mat<T>& operator=(const Mat<T>& m);
+
+        ~Mat();
+
+        int getLine() const;
+        int getColumn() const;
+
+        T get(int line, int column) const;
+        void set(T value, int line, int column);
+        void afficher();
+        void afficherM();
+
+        bool getDeterm() const;
+        T getDet() const;
+        bool getCommut() const;
+        Mat<T> getComm() const;
+        bool getInverse() const;
+        Mat<T> getInv();
+
+        void computeDeterminant( bool again = false);
+        void computeCommutants( bool again = false);
+        int computeInv(bool again = false);
+
+        void swap(int i1, int j1, int i2, int j2);
+        void swapL(int i1, int i2);
+        void swapC(int j1, int j2);
+        void updateC();
+        /*accuracy*/
+        /*roundoff error : zero validation */
+        void roundoff();
+
+
+};
+
+template<typename T>
+bool operator==(const Mat<T>& a, const Mat<T>& b);
+template<typename T>
+bool operator>=(const Mat<T>& a, const Mat<T>& b);
+template<typename T>
+bool operator<=(const Mat<T>& a, const Mat<T>& b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator*(const Mat<T>& a, const Mat<T>& b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator*(const T& v, const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator+(const Mat<T>& a, const Mat<T>& b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator-(const Mat<T>& a, const Mat<T>& b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator%(const Mat<T>& a, const Mat<T>& b);     /*usage du modulo comme produit coefficient à coefficient*/
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operatorL(const Mat<T>& a, const Mat<T>& b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Line( const Mat<T>& a, int ind);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operatorC(const Mat<T>& a, const Mat<T>& b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Col( const Mat<T>& a, int ind);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Cola( const Mat<T> a, int ind);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> extract(Mat<T> m, int ib, int jb, int ie, int je);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> transpose(const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> inv(const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sum(const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> log(const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T fabs_(T a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> absM(const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sqrt(const Mat<T>& a);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T dist( const Mat<T>& a, const Mat<T>& b, int method = 2);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T atan21( T y, T x);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> atan2(const Mat<T>& y, const Mat<T>& x);
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T var(Mat<T> mat);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T covar(Mat<T> a, Mat<T> b);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T sigmoid( const T z);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sigmoidM(const Mat<T>& z);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sigmoidGradM( const Mat<T>& z);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> derive(Mat<T> m, int k, int l);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> pict2mat(const FILE* file);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T detRec(const Mat<T>& m);
+
+#ifdef OPENCV_USE
+/*convertion des matrice de OPENCV en Mat<T> dans le tableau tab.*/
+/*renvoi le nombre de matrice cotenue finalement dans tab, */
+/*correspondant au nombre de channel de mat.*/
+
+/*
+template<typename T>    //pas de point virgule en fin de ligne...
+int cv2Mat(const cv::Mat mat, Mat<T>* tab);
+//Mat<T> cv2Mat( cv::Mat& img);
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2CV( Mat<T>* tab);
+
+template<typename T>    //pas de point virgule en fin de ligne...
+Mat<T> cv2Mat(const cv::Mat mat);
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2CV( Mat<T> tab);
+*/
+template<typename T>    //pas de point virgule en fin de ligne...
+int cv2Mat(const cv::Mat mat, Mat<T>* r, Mat<T>* g, Mat<T>* b);
+template<typename T>    //pas de point virgule en fin de ligne...
+int cv2MatAt(const cv::Mat mat, Mat<T>* r, Mat<T>* g, Mat<T>* b);
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2cv(Mat<T>* r, Mat<T>* g, Mat<T>* b);
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2cvVec(Mat<T> r, Mat<T> g, Mat<T> b);
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2cvAt(Mat<T> r, Mat<T> g, Mat<T> b);
+#endif
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> correlation(Mat<T> m, Mat<T> k);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T max(Mat<T> mat);
+template<typename T>
+Mat<T> idmin(Mat<T> mat);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T mean(Mat<T> mat);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> meanC(Mat<T> mat);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> pooling(Mat<T> m, Mat<T> k, int type = 1);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sym(Mat<T> m);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> convolution(Mat<T> m, Mat<T> k);
+template<typename T>
+Mat<T> conv(Mat<T> m, Mat<T> k);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void homogeneousNormalization( Mat<T>* X);
+
+
+/*--------------------------------------------*/
+/*--------------------------------------------*/
+/*fin des definitions des prototypes*/
+/*--------------------------------------------*/
+/*--------------------------------------------*/
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat()
+{
+    m_line = 1;
+    m_column = 1;
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();
+
+    /*
+    mat = new T*[m_line];
+
+    for(int i=0;i<=m_line-1;i++)
+        mat[i] = new T[m_column];
+    */
+    mat = new T[m_line*m_column];
+
+    /*
+    roundoffmat = new T*[m_line];
+
+    for(int i=0;i<=m_line-1;i++)
+        roundoffmat[i] = new T[m_column];
+    */
+
+    carre = NULL;
+}
+
+
+/*---------------------------------------------*/
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat(const Mat<T>& m, bool sq)
+{
+    m_line = m.getLine();
+    m_column = m.getColumn();
+    determ = m.getDeterm();
+    det = m.getDet();
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();
+
+    /*
+    mat = new T*[m_line];
+
+    for(int i=1;i<=m_line;i++)
+    {
+        mat[i-1] = new T[m_column];
+
+        for(int j=1;j<=m_column;j++)
+        {
+            mat[i-1][j-1] = m.get(i,j);
+        }
+    }
+    */
+    mat = new T[m_line*m_column];
+
+    for(int i=1;i<=m_line;i++)
+    {
+        for(int j=1;j<=m_column;j++)
+        {
+            this->set(m.get(i,j), i,j);
+        }
+    }
+
+    if(sq)
+    {
+        if( m_line != m_column)
+            carre = new Mat<T>(transpose(m)*m);
+        else
+            carre = NULL;
+    }
+    else
+        carre = NULL;
+
+}
+
+/*---------------------------------------------*/
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat(const Mat<T>& m, T oValue, int d_line, int d_column, int line, int column, bool sq)
+{
+    m_line = line;
+    m_column = column;
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();
+
+    /*
+    mat = new T*[m_line];
+
+    for(int i=m_line;i--;)
+        mat[i] = new T[m_column];
+        */
+    mat = new T[m_line*m_column];
+
+
+    carre = NULL;
+
+    /*
+    if( m.getColumn()+d_column-1<=m_column && m.getLine()+d_line-1<=m_line )
+    {
+        for(int i=m_line;i--;)
+        {
+            for(int j=m_column;j--;)
+            {
+                if( i>=d_line && i<=d_line+m.getLine()-1 && j>=d_column && j<=d_column+m.getColumn()-1)
+                    mat[i][j] = m.get(i-d_line+1,j-d_column+1);
+                else
+                    mat[i][j] = oValue;
+            }
+        }
+
+        if(sq)
+        {
+            if( m_line != m_column)
+                carre = new Mat<T>(transpose(m)*m);
+            else
+                carre = NULL;
+        }
+        else
+            carre = NULL;
+    }
+    else
+    {
+        cerr << "Attention : les parametres specifies ne permettent pas l'initialisation de la matrice : " << endl;
+        cerr << "m = " << m.getLine() << " " << m.getColumn() << endl;
+        cerr << d_line << " " << d_column << endl;
+        cerr << m_line << " " << m_column << endl;
+    }
+    */
+    if( m.getColumn()+d_column-1<=m_column && m.getLine()+d_line-1<=m_line )
+    {
+        for(int i=m_line;i--;)
+        {
+            for(int j=m_column;j--;)
+            {
+                if( i>=d_line && i<=d_line+m.getLine()-1 && j>=d_column && j<=d_column+m.getColumn()-1)
+                    this->set( m.get(i-d_line+1,j-d_column+1), i+1, j+1);
+                else
+                    this->set(oValue, i+1,j+1);
+            }
+        }
+
+        if(sq)
+        {
+            if( m_line != m_column)
+                carre = new Mat<T>(transpose(m)*m);
+            else
+                carre = NULL;
+        }
+        else
+            carre = NULL;
+    }
+    else
+    {
+        cerr << "Attention : les parametres specifies ne permettent pas l'initialisation de la matrice : " << endl;
+        cerr << "m = " << m.getLine() << " " << m.getColumn() << endl;
+        cerr << d_line << " " << d_column << endl;
+        cerr << m_line << " " << m_column << endl;
+    }
+
+
+
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat(const Mat<T>& m, int delLine[], int cLine, int delColumn[], int cColumn, bool sq)
+{
+    m_line = m.getLine() - cLine; /*sizeof(delLine);*/
+    m_column = m.getColumn() - cColumn; /*sizeof(delColumn);*/
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();
+
+    int m_i = 1;
+    int m_j = 1;
+
+    carre = NULL;
+
+    /*
+    if((m_line > 0) && (m_column > 0))
+    {
+        mat = new T*[m_line];
+
+        for(int i=m_line;i--;)
+            mat[i] = new T[m_column];
+
+        for(int i=1;m_i<=m_line;i++)
+        {
+            bool continuer = true;
+            int h = (int)(sizeof(delLine)/sizeof(int));
+
+            for(int j=0;j<=h-1;j++)
+            {
+                if(i==delLine[j])
+                    continuer = false;
+            }
+
+            if(continuer)
+            {
+                m_j = 1;
+
+                for(int j=1;m_j<=m_column;j++)
+                {
+                    continuer = true;
+                    int w = (int)(sizeof(delColumn)/sizeof(int));
+
+                    for(int k=0;k<=w-1;k++)
+                    {
+                        if(j==delColumn[k])
+                            continuer = false;
+                    }
+
+                    if(continuer)
+                    {
+                        mat[m_i-1][m_j-1] = m.get(i,j);
+                        m_j++;
+                    }
+                }
+
+                m_i++;
+            }
+        }
+        */
+    if((m_line > 0) && (m_column > 0))
+    {
+        mat = new T[m_line*m_column];
+
+        for(int i=1;m_i<=m_line;i++)
+        {
+            bool continuer = true;
+            int h = (int)(sizeof(delLine)/sizeof(int));
+
+            for(int j=0;j<=h-1;j++)
+            {
+                if(i==delLine[j])
+                    continuer = false;
+            }
+
+            if(continuer)
+            {
+                m_j = 1;
+
+                for(int j=1;m_j<=m_column;j++)
+                {
+                    continuer = true;
+                    int w = (int)(sizeof(delColumn)/sizeof(int));
+
+                    for(int k=0;k<=w-1;k++)
+                    {
+                        if(j==delColumn[k])
+                            continuer = false;
+                    }
+
+                    if(continuer)
+                    {
+                        this->set(m.get(i,j), m_i, m_j);
+                        m_j++;
+                    }
+                }
+
+                m_i++;
+            }
+        }
+
+
+
+        if(sq)
+        {
+            if( m_line != m_column)
+                carre = new Mat<T>(transpose(m)*m);
+            else
+                carre = NULL;
+        }
+        else
+            carre = NULL;
+
+    }
+    else
+    {
+        cerr << "ERREUR : les parametres specifies ne permettent pas l'initialisation de la matrice." << endl;
+    }
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat( int line, int column)
+{
+    m_line = line;
+    m_column = column;
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();
+
+    /*
+    mat = new T*[line];
+
+    for(int i=0;i<=line-1;i++)
+        mat[i] = new T[column];
+    */
+    mat = new T[line*column];
+
+    carre = NULL;
+
+}
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat( int line, int column, char mode)
+{    
+    m_line = line;
+    m_column = column;
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();
+
+    /*
+    mat = new T*[line];
+
+    for(int i=0;i<=line-1;i++)
+        mat[i] = new T[column];
+    */
+    mat = new T[line*column];
+
+    carre = NULL;
+
+    if(mode == 1)   //random
+    {
+        srand(time(NULL));
+
+        for(int i=1;i<=m_line;i++)
+            for(int j=1;j<=m_column;j++)    this->set( (T) (rand()%(int)maxi), i,j);
+    }
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::Mat( T value, int line, int column, bool sq)
+{    
+    m_line = line;
+    m_column = column;
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+    inv = NULL;
+    inverse = false;
+    epsilon = numeric_limits<T>::epsilon();    
+
+    /*
+    mat = new T*[line];
+
+    for(int i=0;i<=line-1;i++)
+    {
+        mat[i] = new T[column];
+
+        for(int j=0;j<=column-1;j++)
+            mat[i][j] = value;
+    }
+    */
+    mat = new T[line*column];
+
+    for(int i=line;i--;)
+    {
+        for(int j=column;j--;)
+            this->set(value, i+1, j+1);
+    }
+
+
+    if(sq)
+    {
+        if( m_line != m_column)
+            carre = new Mat<T>(transpose(*this)*(*this));
+        else
+            carre = NULL;
+    }
+    else
+        carre = NULL;
+
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>::~Mat()
+{
+    /*
+    for(int i=0;i<=m_line-1;i++)
+    {
+        delete[] mat[i];
+        //delete[] roundoffmat[i];
+    }
+    */
+    delete[] mat;
+    //delete roundoffmat;
+
+    if(commut || comm != NULL)
+    {
+        delete(comm);
+    }
+
+    if(inverse || inv != NULL)
+    {
+        delete(inv);
+    }
+
+    if(carre != NULL)
+        delete carre;
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+int Mat<T>::getLine() const
+{
+    return m_line;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+int Mat<T>::getColumn() const
+{
+    return m_column;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+inline T Mat<T>::get(int line, int column) const
+{
+    if(line <= m_line && column <= m_column && line >=1 && column >=1 )
+        return mat[(line-1)*m_column + (column-1)];//return mat[line-1][column-1];
+
+
+    return (T)0;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+inline void Mat<T>::set(T value, int line, int column)
+{
+    if(line >= 1 && line <= m_line && column >= 1 && column <= m_column)
+        mat[(line-1)*m_column + (column-1)] = (T)value;//mat[line-1][column-1] = value;
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::roundoff()
+{
+    for(int i=1;i<=m_line;i++)
+    {
+        for(int j=1;j<=m_line; j++)
+        {
+            this->set( (this->get(i,j)<= this->epsilon ? (T)0 : this->get(i,j)), i,j);
+        }
+    }
+
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::afficher()
+{
+    cout << "Matrice :" << endl;
+    //this->roundoff();
+
+        for(int i=1;i<=m_line;i++)
+        {
+            for(int j=1;j<=m_column;j++)
+            {
+                cout << "  " << this->get(i,j) ;
+                //cout << "  " << ( fabs_(this->get(i,j)) >= epsilon*10e2 ? this->get(i,j) : (T)0) ;
+                //cout << "  " << roundoffmat[i-1][j-1] ;
+            }
+
+            cout << endl;
+        }
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::afficherM()
+{
+    pcm.printf("Matrice : \n");
+    //this->roundoff();
+
+        for(int i=1;i<=m_line;i++)
+        {
+            for(int j=1;j<=m_column;j++)
+            {
+                pcm.printf("  %f", this->get(i,j));
+                //cout << "  " << ( fabs_(this->get(i,j)) >= epsilon*10e2 ? this->get(i,j) : (T)0) ;
+                //cout << "  " << roundoffmat[i-1][j-1] ;
+            }
+
+            pcm.printf("\n");
+        }
+}
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator*(const Mat<T>& a, const Mat<T>& b)
+{    
+    if(a.getColumn() != b.getLine())
+    {
+        
+        pcm.printf("Impossible d'operer la multiplication : mauvais formats de matrices.\n");
+        //pcm.printf("Format m1 : " << a.getLine() << " x " << a.getColumn() << "\t Fromat m2 : " << b.getLine() << " x " << b.getColumn() << endl;
+        return Mat<T>(1,1);
+    }
+        
+    Mat<T> r( a.getLine(), b.getColumn());    
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {                        
+            T temp = (T)0;
+            for(int k=1;k<=a.getColumn();k++)
+                temp += a.get(i,k)*b.get(k,j);
+
+            r.set( temp, i, j);
+        }
+    }        
+
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator*(const T& v, const Mat<T>& a)
+{
+    Mat<T> r(a);
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( (T)(v*r.get(i,j)), i, j);
+        }
+    }
+
+
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator+(const Mat<T>& a, const Mat<T>& b)
+{
+    if((a.getColumn() != b.getColumn()) || (a.getLine() != b.getLine()))
+    {
+        cerr << "Impossible d'operer l'addition : mauvais formats de matrices.\n" << endl;
+        cerr << "Format m1 : " << a.getLine() << " x " << a.getColumn() << "\t Fromat m2 : " << b.getLine() << " x " << b.getColumn() << endl;
+        return Mat<T>(1,1);
+    }
+
+    Mat<T> r( a.getLine(), b.getColumn());
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( a.get(i,j)+b.get(i,j) , i, j);
+        }
+    }
+
+
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator-(const Mat<T>& a, const Mat<T>& b)
+{
+    if((a.getColumn() != b.getColumn()) || (a.getLine() != b.getLine()))
+    {
+        cerr << "Impossible d'operer la soustraction : mauvais formats de matrices.\n" << endl;
+        cerr << "Format m1 : " << a.getLine() << " x " << a.getColumn() << "\t Fromat m2 : " << b.getLine() << " x " << b.getColumn() << endl;
+        return Mat<T>(1,1);
+    }
+
+    Mat<T> r(a.getLine(), b.getColumn());
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( a.get(i,j)-b.get(i,j) , i, j);
+        }
+    }
+
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operator%(const Mat<T>& a, const Mat<T>& b)
+{
+    if((a.getColumn() != b.getColumn()) || (a.getLine() != b.getLine()))
+    {
+        cerr << "Impossible d'operer la multiplication c_a_c : mauvais formats de matrices.\n" << endl;
+        cerr << "Format m1 : " << a.getLine() << " x " << a.getColumn() << "\t Fromat m2 : " << b.getLine() << " x " << b.getColumn() << endl;
+        return Mat<T>(1,1);
+    }
+
+    Mat<T> r(a.getLine(), a.getColumn());
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( a.get(i,j)*b.get(i,j), i, j);
+        }
+    }
+
+
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::copy(const Mat<T>& m)
+{
+    m_line = m.getLine();
+    m_column = m.getColumn();
+    determ = false;
+    det = 0;
+    comm = NULL;
+    commut = false;
+
+    /*
+    mat = new T*[m_line];
+
+    for(int i=0;i<=m_line-1;i++)
+    {
+        mat[i] = new T[m_column];
+
+        for(int j=0;j<=m_column-1;j++)
+        {
+            mat[i][j] = m.get(i+1,j+1);
+        }
+    }
+    */
+    mat = new T[m_line*m_column];
+
+    for(int i=m_line;i--;)
+    {
+        for(int j=m_column;j--;)
+        {
+            this->set( m.get(i+1,j+1), i+1,j+1);
+        }
+    }
+
+
+    if( m_line != m_column)
+        carre = new Mat<T>(transpose(*this)*(*this));
+    else
+        carre = NULL;
+
+}
+
+
+/*---------------------------------------------*/
+
+
+
+
+
+template<typename T>
+bool operator==(const Mat<T>& a, const Mat<T>& b)
+{
+    bool r = true;
+    bool continuer = true;
+    
+    if(a.getLine() == b.getLine() && a.getColumn() == b.getColumn() )
+    {
+        for(int i=1;i<=a.getLine();i++)
+        {
+            for(int j=1;j<=a.getColumn();j++)
+            {
+                if(a.get(i,j) != b.get(i,j))
+                {
+                    r = false;
+                    continuer = false;
+                }
+                
+                if(!continuer)
+                    j=a.getColumn();
+            }
+            
+            if(!continuer)
+                i=a.getLine();
+        }
+    }
+    else
+        r = false;
+    
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+
+
+template<typename T>
+bool operator<=(const Mat<T>& a, const Mat<T>& b)
+{
+    bool r = true;
+    bool continuer = true;
+    
+    if(a.getLine() == b.getLine() && a.getColumn() == b.getColumn() )
+    {
+        for(int i=1;i<=a.getLine();i++)
+        {
+            for(int j=1;j<=a.getColumn();j++)
+            {
+                if(a.get(i,j) > b.get(i,j))
+                {
+                    r = false;
+                    continuer = false;
+                }
+                
+                if(!continuer)
+                    j=a.getColumn();
+            }
+            
+            if(!continuer)
+                i=a.getLine();
+        }
+    }
+    else
+        r = false;
+    
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+
+
+template<typename T>
+bool operator>=(const Mat<T>& a, const Mat<T>& b)
+{
+    bool r = true;
+    bool continuer = true;
+    
+    if(a.getLine() == b.getLine() && a.getColumn() == b.getColumn() )
+    {
+        for(int i=1;i<=a.getLine();i++)
+        {
+            for(int j=1;j<=a.getColumn();j++)
+            {
+                if(a.get(i,j) < b.get(i,j))
+                {
+                    r = false;
+                    continuer = false;
+                }
+                
+                if(!continuer)
+                    j=a.getColumn();
+            }
+            
+            if(!continuer)
+                i=a.getLine();
+        }
+    }
+    else
+        r = false;
+    
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T>& Mat<T>::operator=(const Mat<T>& m)
+{
+    if(this != &m)
+    {
+        this->~Mat();
+        //this->Mat<T>(m);
+        this->copy(m);
+        /*on ne peut pas appeller le constructeur de copie...?*/
+    }
+
+    return *this;
+}
+/*La seconde chose à savoir est que le compilateur génère un opérateur d'affectation automatiquement si vous ne le faites pas, et que celui-ci sera suffisant dans la plupart des cas. Vous pouvez donc parfois tout simplement éviter de l'écrire. */
+
+/*De même, imaginez que l'appel à new échoue (ce qui peut très bien arriver) : la ressource aura déjà été détruite, mais ne sera pas recréée, laissant l'objet dans un état invalide, et menant là encore à des comportements indéterminés. */
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operatorC(const Mat<T>& a, const Mat<T>& b)
+{
+    if(a.getColumn()==b.getColumn())
+    {
+        Mat<T> r(a, (T)0, (int)1, (int)1, a.getLine()+b.getLine(), a.getColumn());
+
+        for(int i=a.getLine()+1;i<=r.getLine();i++)
+        {
+            for(int j=1;j<=r.getColumn();j++)
+            {
+                r.set(b.get(i-a.getLine(),j),i,j);
+            }
+        }
+
+        return r;
+    }
+    else
+    {
+        cout << "Erreur : impossible de concatener les deux matrices sur les colonnes." << endl;
+        return Mat<T>( 1, 1);
+    }
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> operatorL(const Mat<T>& a, const Mat<T>& b)
+{
+    if(a.getLine()==b.getLine())
+    {
+        Mat<T> r(a, (T)0, (int)1, (int)1, a.getLine(), a.getColumn()+b.getColumn());
+
+        for(int i=1;i<=r.getLine();i++)
+        {
+            for(int j=a.getColumn()+1;j<=r.getColumn();j++)
+            {
+                r.set(b.get(i,j-a.getColumn()),i,j);
+            }
+        }
+
+        return r;
+    }
+    else
+    {
+        cout << "Erreur : impossible de concatener les deux matrices sur les lignes." << endl;
+        pcm.printf("Erreur : impossible de concatener les deux matrices sur les lignes.");
+        return Mat<T>(1, 1);
+    }
+
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Line( const Mat<T>& a, int ind)
+{
+    /*
+    int* delLine = NULL;
+    delLine = (int*)malloc(sizeof(int)*(a.getLine()-1));
+
+    int delColumn[1];
+    int cLine = a.getLine()-1;
+    int cColumn = 0;
+
+    int k = 0;
+    for(int i=1;i<=a.getLine();i++)
+    {
+        if(ind != i)
+        {
+            delLine[k] = i;
+            k++;
+        }
+    }
+
+    Mat<T> r( a, delLine, cLine, delColumn, cColumn);
+    */
+    int m = a.getColumn();
+    Mat<T> r(1, m);
+
+    for(int i=1;i<=m;i++)   r.set( a.get(ind, i), 1,i);
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Col( const Mat<T>& a, int ind)
+{
+    int* delColumn = NULL;
+    delColumn = (int*)malloc(sizeof(int)*(a.getColumn()-1));
+
+    int delLine[1];
+    int cColumn = a.getColumn()-1;
+    int cLine = 0;
+
+    int k = 0;
+    for(int i=1;i<=a.getColumn();i++)
+    {
+        if(ind != i)
+        {
+            delColumn[k] = i;
+            k++;
+        }
+    }
+
+    Mat<T> r( a, delLine, cLine, delColumn, cColumn);
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Cola( const Mat<T> a, int ind)
+{
+    Mat<T> r((T)0, a.getLine(), 1);
+
+    if( ind<= a.getColumn() && ind >=1)
+        for(int i=1;i<=a.getLine();i++) r.set( a.get(i,ind), i, 1);
+
+    return r;
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> transpose(const Mat<T>& a)
+{
+    Mat<T> r(a.getColumn(), a.getLine());
+
+    for(int i=1;i<=a.getColumn();i++)
+    {
+        for(int j=1;j<=a.getLine();j++)
+        {
+            r.set( a.get(j,i), i, j);
+        }
+    }
+
+    return r;
+}
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> inv(const Mat<T>& a)
+{
+    Mat<T> temp(transpose(a)*a);
+
+
+    //temp.computeInv();
+    Mat<T> b((T)0, temp.getLine(), 1);
+    gaussj(&temp, &b, 1);
+
+    return temp*transpose(a);
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sum(const Mat<T>& a)
+{
+    if(a.getColumn()!=1)
+    {
+        /*sum on columns*/
+        Mat<T> r( 1, a.getLine());
+
+        for(int j=1;j<=a.getColumn();j++)
+        {
+            T temp = 0;
+            for(int i=1;i<=a.getLine();i++)
+                temp += a.get(i,j);
+
+            r.set(temp, 1,j);                   /* [0 ; n] x [0 ; m] !!!! */
+        }
+
+        return r;
+    }
+    else
+    {
+        /*sum on the only column*/
+        Mat<T> r( 1, 1);
+
+        for(int i=1;i<=a.getLine();i++)
+        {
+            r.set((r.get(1,1)+a.get(i,1)), 1,1);            /* [0 ; n] x [0 ; m] !!!! */
+        }
+
+        return r;
+    }
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T sigmoid( const T z)
+{
+    return 1/exp(-z);
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sigmoidM(const Mat<T>& z)
+{
+    Mat<T> r(z);
+
+
+    for(int i=1;i<=z.getLine();i++)
+    {
+        for(int j=1;j<=z.getColumn();j++)
+        {
+            r.set(sigmoid(z.get(i,j)),i,j);
+        }
+    }
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sigmoidGradM( const Mat<T>& z)
+{
+    Mat<T> one((T)(1), z.getLine(), z.getColumn());
+    Mat<T> r(sigmoidM(z) % (one - sigmoidM(z)));    //  sigmoid(z).*(ones(size(z))-sigmoid(z));
+
+    return r;
+}
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> log(const Mat<T>& a)
+{
+    Mat<T> r(a);
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( log<T>(r.get(i,j)), i,j);
+        }
+    }
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> absM(const Mat<T>& a)
+{
+    Mat<T> r(a);
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( fabs( r.get(i,j)), i,j);
+        }
+    }
+
+    return r;
+
+}
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> sqrt(const Mat<T>& a)
+{
+    Mat<T> r(a);
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set( sqrt(r.get(i,j)), i,j);
+        }
+    }
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T dist( const Mat<T>& a, const Mat<T>& b, int method)   /*method 2 : euclidian distance, else : L1*/
+{
+    T r = 0;
+    Mat<T> temp = a-b;
+    r= (method == 2 ? sqrt( sum( sum( temp%temp )).get(1,1) ) : sum( sum( absM(temp) ) ).get(1,1) );
+
+    return r;
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T atan21( T y, T x)
+{
+    T r = y;
+
+    if( x!= 0)
+    {
+        if(x < 0)
+        {
+            if(y<0)
+                r = -PI + atan(y/x);
+            else
+                r = PI/2 + atan(y/x);
+        }
+        else
+            r = atan(y/x);
+    }
+    else
+        r = ( y <= 0 ? -PI/2 : PI/2);
+
+    return r;
+
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+
+Mat<T> atan2(const Mat<T>& y, const Mat<T>& x)
+{
+    Mat<T> r(y);
+
+    if(x.getColumn() == y.getColumn() && x.getLine() == y.getLine())
+    {
+        for(int i=1;i<=r.getLine();i++)
+        {
+            for(int j=1;j<=r.getColumn();j++)
+            {
+                r.set( atan21(r.get(i,j), x.get(i,j) ), i,j);
+            }
+        }
+    }
+    else
+    {
+        cerr << "ERREUR : atan : les matrices ne sont pas de memes dimensions." << endl;
+    }
+
+    return r;
+
+}
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T var(Mat<T> mat)
+{
+    T r = 0;
+
+    if(mat.getColumn()==1 && mat.getLine() != 1)
+    {
+        int n = mat.getLine();
+        T mu = 0;
+        for(int i=1;i<=n;i++)
+            mu += (T)(((T)1.0/(T)n))*mat.get(i,1);
+        cout << mu << endl;
+
+        for(int i=1;i<=n;i++)
+            r += (T)(((T)1/(T)(n-1)))*(mat.get(i,1)-mu)*(mat.get(i,1)-mu);
+    }
+
+    return r;
+}
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T covar(Mat<T> a, Mat<T> b)
+{
+    T r = 0;
+
+    if((a.getColumn()==1 && a.getLine() != 1) &&(b.getColumn()==1 && b.getLine() != 1) && a.getLine() == b.getLine())
+    {
+        int na = a.getLine();
+        T mua = 0;
+        T mub = 0;
+        for(int i=1;i<=na;i++)
+        {
+            mua += ((T)1/na)*a.get(i,1);
+            mub += ((T)1/na)*b.get(i,1);
+        }
+
+        for(int i=1;i<=na;i++)
+            r += (T)((T)1/(na-1))*(a.get(i,1)-mua)*(b.get(i,1)-mub);
+    }
+
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> derive(Mat<T> m, int k, int l)
+{
+    Mat<T> r((T)0, m.getLine(), m.getColumn());
+    r.set( (T)1, k,l);
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+bool Mat<T>::getDeterm() const
+{
+    return determ;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T Mat<T>::getDet() const
+{
+    /*computeDeterminant(false);*/
+    return det;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T detRec(const Mat<T>& m)
+{
+    if(m.getLine()==2)
+        return (m.get(1,1)*m.get(2,2)-m.get(2,1)*m.get(1,2));
+    else if(m.getLine()==1)
+        return m.get(1,1);
+    else
+    {
+        int line = m.getLine();
+        /*int column = m.getColumn();*/
+        T sum = 0;
+
+        /* developpement sur la première colonne...*/
+
+        for(int i=1;i<=line;i++)
+        {
+            int tabL[1] = {i};
+            int tabC[1] = {1};
+            Mat<T> s_m(m, tabL, 1, tabC, 1);
+
+            if((i+1)%2)
+                sum -= m.get(i,1)*detRec(s_m);
+            else
+                sum += m.get(i,1)*detRec(s_m);
+        }
+
+        return sum;
+    }
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+bool Mat<T>::getCommut() const
+{
+    return commut;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Mat<T>::getComm() const
+{
+    if(commut)
+        return *comm;
+    else
+        return Mat<T>(1,1);
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+bool Mat<T>::getInverse() const
+{
+    return inverse;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Mat<T>::getInv()
+{
+    computeInv();
+    return *inv;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::updateC()
+{
+    if(m_line != m_column)
+    {
+        if(carre == NULL)
+        {
+            carre = new Mat<T>(transpose(*this) * (*this) );
+        }
+        else
+        {
+            *carre = transpose(*this)*(*this);
+        }
+    }
+    else
+    {
+        if(carre != NULL)
+        {
+            delete carre;
+            carre = NULL;
+        }
+    }
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::computeDeterminant( bool again)
+{
+    if((determ && again) || !determ)
+    {
+        if(m_line == m_column)
+        {
+            determ = true;
+            det = detRec(*this);
+        }
+        else
+        {
+            updateC();
+
+            determ = true;
+            det = detRec(*carre);
+
+            cout << "Impossible de calculer le determinant de cette matrice normalement : elle n'est pas carree." << endl;
+            cout << "PSEUDOINVERSE" << endl;
+        }
+    }
+
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+
+void Mat<T>::computeCommutants( bool again)
+{
+    if((commut && again) || !commut)
+    {
+        if(m_line == m_column)
+        {
+            commut = true;
+
+            comm = new Mat<T>(*this);
+
+            for(int i=1;i<=m_line;i++)
+            {
+                for(int j=1;j<=m_column;j++)
+                {
+                    int tabL[1] = {i};
+                    int tabC[1] = {j};
+                    Mat<T> temp(*this, tabL, 1, tabC, 1);
+
+                    temp.computeDeterminant();
+
+                    if((i+j)%2)
+                        comm->set( (T)(-temp.getDet()), i,j);
+                    else
+                        comm->set( temp.getDet(), i, j);
+                }
+            }
+        }
+        else
+        {
+            updateC();
+
+            commut = true;
+            comm = new Mat<T>(*carre);
+
+            for(int i=1;i<=comm->getLine();i++)
+            {
+                for(int j=1;j<=comm->getColumn();j++)
+                {
+                    int tabL[1] = {i};
+                    int tabC[1] = {j};
+                    Mat<T> temp(*carre, tabL, 1, tabC, 1);
+
+                    temp.computeDeterminant();
+
+                    if((i+j)%2)
+                        comm->set( (T)(-temp.getDet()), i,j);
+                    else
+                        comm->set( temp.getDet(), i, j);
+                }
+            }
+
+            cout << "PSEUDOINVERSE : commutants" << endl;
+        }
+    }
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+int Mat<T>::computeInv(bool again)
+{
+    if((inverse && again) || !inverse)
+    {
+        if(determ && commut)
+        {
+            if(det != 0)
+            {
+                inverse = true;
+
+                if(m_line == m_column)
+                {
+                    inv = new Mat<T>((T)(1/(this->getDet()))*transpose(*comm));
+                }
+                else
+                {
+                    inv = new Mat<T>( ((T)(1/(this->getDet())))*transpose(*comm) * transpose(*this) );
+                }
+            }
+            else
+            {
+                cout << "Impossible de calculer l'inverse de la matrice, celle-ci a un determinant nul." << endl;
+                return 0;
+            }
+        }
+        else
+        {
+            computeDeterminant();
+            computeCommutants();
+            computeInv();
+        }
+    }
+
+    return 1;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::swap(int i1, int j1, int i2, int j2)
+{
+    T temp = this->get(i1,j1);
+    this->set( this->get(i2,j2), i1, j1);
+    this->set( temp, i2, j2);
+}
+
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::swapL(int i1, int i2)
+{
+    for(int j=1;j<=this->getColumn();j++)   this->swap(i1, j, i2, j);
+}
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void Mat<T>::swapC(int j1, int j2)
+{
+    for(int i=1;i<=this->getLine();i++) this->swap(i, j1, i, j2);
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> extract(Mat<T> m, int ib, int jb, int ie, int je)
+{
+    Mat<T> r((T)0, ie-ib+1, je-jb+1);
+
+    for(int i=1;i<=r.getLine();i++)
+    {
+        for(int j=1;j<=r.getColumn();j++)
+        {
+            r.set(m.get(ib+i-1,jb+j-1), i, j);
+        }
+    }
+
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+void homogeneousNormalization( Mat<T>* X)
+{
+    int n = X->getLine();
+    int m = X->getColumn();
+
+    for(int j=1;j<=m;j++)
+    {
+        T l = X->get(n,j);
+        for(int i=1;i<=n;i++)   X->set( (l != 0 ? X->get(i,j)/l : X->get(i,j)), i,j);
+    }
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> correlation(Mat<T> m, Mat<T> k)
+{
+    Mat<T> r(m);
+    int mi = m.getLine();
+    int mj = m.getColumn();
+    int ki = k.getLine();
+    int kj = k.getColumn();
+
+    if(mj >= kj && mi >= ki)
+    {
+        for(int i=1;i<=mi;i++)
+        {
+            for(int j=1;j<=mj;j++)
+            {
+                //T temp = sum(sum(k%extract(m, i-ki/2, j-kj/2, i+ki/2, j+kj/2))).get(1,1);
+                T temp = 0;
+
+                for(int ii=i-ki/2;ii<=i+ki/2;ii++)
+                    for(int jj=j-kj/2;jj<=j+kj/2;jj++)
+                        temp += k.get(ii-i+ki/2+1,jj-j+kj/2+1)*m.get(ii,jj);
+
+                r.set( temp, i, j);
+            }
+        }
+    }
+    else
+    {
+        cout << "ERREUR : correlation impossible, l'image est plus petite que le kernel..." << endl;
+    }
+
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> conv(Mat<T> m, Mat<T> k)
+{   
+    int mi = m.getLine();
+    int mj = m.getColumn();
+    int ki = k.getLine();
+    int kj = k.getColumn();
+    Mat<T> r((T)0, (int)(mi/ki+1), (int)(mj/kj+1));
+        
+    if(mj/kj >= 1 && mi/ki >= 1)
+    {
+        for(int i=1;i<=mi/ki;i++)
+        {
+            for(int j=1;j<=mj/kj;j++)
+            {
+                T temp = sum(sum(k % extract(m, (i-1)*ki +1,(j-1)*kj+1, i*ki, j*kj ) ) ).get(1,1);
+                r.set( temp, i, j);
+            }
+        }
+    }
+    else
+    {
+        cout << "ERREUR : conv impossible, l'image est plus petite que le kernel..." << endl;
+    }
+    
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T mean(Mat<T> mat)
+{
+    T r = 0;
+    int n = mat.getLine();
+    int m = mat.getColumn();
+
+    for(int i=1;i<=n;i++)
+    {
+        for(int j=1;j<=m;j++)
+        {
+            r += ((T)1/(m*n))*mat.get(i,j);
+        }
+    }
+
+    return r;
+}
+
+
+
+
+/*---------------------------------------------*/
+
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> meanC(Mat<T> mat)
+{
+    int m = mat.getColumn();
+    Mat<T> r(1,m);
+
+    for(int i=1;i<=m;i++)
+    {
+        r.set( mean(Cola(mat, i)), 1,i);
+    }
+
+    return r;
+}
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T max(Mat<T> mat)
+{
+    T r = mat.get(1,1);
+    int n = mat.getLine();
+    int m = mat.getColumn();
+
+    for(int i=1;i<=n;i++)
+    {
+        for(int j=1;j<=m;j++)
+        {
+            T temp = mat.get(i,j);
+            r =  (r>= temp ? r : temp);
+        }
+    }
+
+    return r;
+}
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>
+Mat<T> idmin(Mat<T> mat)
+{
+    Mat<T> r((T)0, 2,1);
+    Mat<T> id(2,1); 
+    int n = mat.getLine();
+    int m = mat.getColumn();
+    
+    for(int i=1;i<=n;i++)
+    {
+        for(int j=1;j<=m;j++)
+        {
+            T temp = mat.get(i,j);
+            id.set((T)i, 1,1);
+            id.set((T)j, 2,1);
+            
+            r =  ( mat.get(r.get(1,1), r.get(2,1)) <= temp ? r : id);
+        }
+    }
+    
+    return r;
+}
+
+/*---------------------------------------------*/
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*type : 1: max 2: mean*/
+/*k : kernel qui specifie en plus la taille de la convolution*/
+/* en mettant une matrice remplie de 1 dans k, on obtient un pooling seul.*/
+Mat<T> pooling(Mat<T> m, Mat<T> k, int type)
+{
+    Mat<T> r(m);
+    int mi = m.getLine();
+    int mj = m.getColumn();
+    int ki = k.getLine();
+    int kj = k.getColumn();
+
+    T (*ptrFonction)(Mat<T>);
+    if(type == 1)
+        ptrFonction = max;
+    else
+        ptrFonction = mean;
+
+    if(mj >= kj && mi >= ki)
+    {
+        for(int i=1;i<=mi/ki;i++)
+        {
+            for(int j=1;j<=mj/kj;j++)
+            {
+                r.set( (*ptrFonction)( k % extract(m, (i-1)*ki+1, (j-1)*kj+1, i*ki+1, j*kj+1) ), i, j);
+            }
+        }
+    }
+    else
+    {
+        cout << "ERREUR : pooling/(filtering) impossible, l'image est plus petite que le kernel..." << endl;
+    }
+
+    return r;
+}
+
+/*
+Mat<T> sym(Mat<T> m)
+{
+
+}
+
+*/
+template<typename T>
+Mat<T> convolution(Mat<T> m, Mat<T> k)
+{
+    int nm = m.getLine();
+    int mm = m.getColumn();
+    int nk = k.getLine();
+    int mk = k.getColumn();
+    
+    int nr = nm/nk;
+    int mr = mm/mk;
+    Mat<T> ret((T)0, nr, mr);
+    
+    for(int i=1;i<=nr;i++)
+    {
+        for(int j=1;j<=mr;j++)
+        {
+            ret.set( (T)( sum( sum( correlation( extract(m, (i-1)*nk+1, (j-1)*mk+1,  i*nk, j*mk), k))) ).get(1,1) , i,j);
+        }
+    }
+    
+    return ret;
+
+}
+
+
+
+#ifdef OPENCV_USE
+
+
+/*---------------------------------------------*/
+
+/*
+template<typename T>    //pas de point virgule en fin de ligne...
+//renvoi le nombre de matrice contenue dans tab,
+//correspondant au nombre de channel de mat.
+
+int cv2Mat(const cv::Mat mat, Mat<T>* tab)
+{
+    int nbr_chan = 0;
+    int r = 0;
+    //int c = 0;
+
+    if(tab != NULL)
+    {
+        nbr_chan = 3; //(int)mat.channels();
+        r = mat.rows;
+        //c = mat.cols;
+
+        cout << "Conversion d'une CvMat<T> avec " << nbr_chan << " channel(s) en " << nbr_chan << " matrices de types Mat<T>." << endl;
+
+        //tab = (Mat<T>**)malloc(sizeof(Mat<T>*)*nbr_chan);
+        //tab = new Mat<T>*[nbr_chan];
+        //tab = new Mat<T>(FLOAT, (T)0, r,c);
+
+
+
+        //for(int k=0;k<=nbr_chan-1;k++)
+        //{
+        //  cout << "begin " << k << endl;
+        //  tab[k] =  new Mat<T>(FLOAT, (T)0, r, c);
+        //}
+
+
+        cv::Mat_<cv::Vec3b>::const_iterator it = mat.begin<cv::Vec3b>();
+        cv::Mat_<cv::Vec3b>::const_iterator itend = mat.end<cv::Vec3b>();
+
+        int i = 0;
+        int j = 0;
+
+
+        for( ; it != itend; ++it)
+        {
+            //cout << i << "/" << r << " & " << j << "/" << c << endl;
+            //tab[0]->set( (*it)[0], i+1,j+1);
+            //tab[1]->set( (*it)[1], i+1,j+1);
+            //tab[2]->set( (*it)[2], i+1,j+1);
+            tab->set( (*it)[0], i+1,j+1);
+
+
+            i++;
+            if( (i+1)%r == 0 )
+            {
+                i=0;
+                j++;
+
+            }
+        }
+
+    }
+    else
+    {
+        cout << "ERREUR : le tableau mis en argument n'est pas NULL. Aucune operation effectuee..." << endl;
+    }
+
+    cout << "end" << endl;
+    cout << tab << endl;
+
+    return nbr_chan;
+}
+
+
+
+//---------------------------------------------
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2CV( Mat<T>* tab)
+{
+    int nbr_chan = 3;
+    int r = tab->getLine();
+    int c = tab->getColumn();
+    cv::Mat mat( r, c, CV_8UC3);
+
+    if(tab != NULL)
+    {
+
+        cout << "Conversion d'une CvMat avec " << nbr_chan << " channel(s) en " << nbr_chan << " matrices de types Mat." << endl;
+        cv::Mat_<cv::Vec3b>::const_iterator it = mat.begin<cv::Vec3b>();
+        cv::Mat_<cv::Vec3b>::const_iterator itend = mat.end<cv::Vec3b>();
+
+        int i = 0;
+        int j = 0;
+
+        for( ; it != itend; ++it)
+        {
+            *it= cv::Vec3b( tab->get(i+1,j+1), tab->get(i+1,j+1), tab->get(i+1,j+1));
+
+            i++;
+            if( !(i+1)%r)
+            {
+                i=0;
+                j++;
+            }
+        }
+
+    }
+    else
+    {
+        cout << "ERREUR : le tableau mis en argument est NULL. Aucune operation effectuee..." << endl;
+    }
+
+    return mat;
+}
+
+
+
+
+
+//---------------------------
+// renvoi les image ou matrice
+//--------------------------
+
+
+
+//---------------------------------------------
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+Mat<T> cv2Mat(const cv::Mat mat)
+{
+    int r = mat.rows;
+    int c = mat.cols;
+    Mat<T> rim( (T)0, r,c);
+
+
+    //time_t timer;
+    //time_t timerp;
+    //time(&timer);
+    //time(&timerp);
+    //cv::Mat_<cv::Vec3b>::const_iterator it = mat.begin<cv::Vec3b>();
+    //cv::Mat_<cv::Vec3b>::const_iterator itend = mat.end<cv::Vec3b>();
+
+    //time(&timer);
+    //cout << timer-timerp << endl;
+
+
+    //int i = 0;
+    //int j = 0;
+
+
+
+    //for( ; it != itend; ++it)
+    //{
+    //  rim.set( (*it)[0], i+1,j+1);
+    //
+    //  i++;
+    //  if( (i+1)%r == 0 )
+    //  {
+    //      i=0;
+    //      j++;
+    //
+    //  }
+    //}
+    //
+
+    for(int x=0;x<=r;x++)
+    {
+            for(int y=0;y<=c;y++)
+            {
+                    rim.set( mat.data[mat.step*y+x+1], x+1, y+1);
+            }
+    }
+
+    return rim;
+}
+
+
+
+
+//---------------------------------------------
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2CV( Mat<T> tab)
+{
+    int r = tab.getLine();
+    int c = tab.getColumn();
+    cv::Mat mat( r, c, CV_8UC3);
+
+    cv::Mat_<cv::Vec3b>::iterator it = mat.begin<cv::Vec3b>();
+    cv::Mat_<cv::Vec3b>::const_iterator itend = mat.end<cv::Vec3b>();
+
+    int i = 0;
+    int j = 0;
+
+    for( ; it != itend; ++it)
+    {
+        *it= cv::Vec3b( tab.get(i+1,j+1), tab.get(i+1,j+1), tab.get(i+1,j+1));
+
+        i++;
+        if( !(i+1)%r)
+        {
+            i=0;
+            j++;
+        }
+    }
+    //
+    //for(int x=0;x<=r;x++)
+    //{
+    //      for(int y=0;y<=c;y++)
+    //      {
+    //              mat.data[mat.step*y+x+1] = (unsigned char)(tab.get(x+1, y+1));
+    //
+    //      }
+    //}
+    //
+    return mat;
+}
+
+
+
+
+
+*/
+/*
+//---------------------------------------------
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+int CvMat2Mat(const CvMat& mat, Mat<T>** tab)
+{
+    int nbr_chan = 0;
+    int r = 0;
+    int c = 0;
+
+    if(tab == NULL)
+    {
+        nbr_chan = (int)mat.channels();
+        r = mat.rows;
+        c = mat.cols;
+
+        cout << "Conversion d'une CvMat avec " << nbr_chan << " channel(s) en " << nbr_chan << " matrices de types Mat." << endl;
+
+        tab = (Mat<T>**)malloc(sizeof(Mat<T>*)*nbr_chan);
+
+        for(int k=0;k<=nbr_chan-1;k++)
+        {
+            tab[k] = (Mat<T>*)malloc(sizeof(Mat<T>));
+            *tab[k] = Mat<T>( r, c);;
+
+            for(int i=1;i<=r;i++)
+            {
+                for(int j=1;j<=c;j++)
+                {
+                    tab[k]->set((T)(mat.at<T>(i-1,j-1)), i, j);
+                }
+            }
+        }
+    }
+    else
+    {
+        cout << "ERREUR : le tableau mis en argument n'est pas NULL. Aucune operation effectuee..." << endl;
+    }
+
+    return nbr_chan;
+}
+*/
+
+/*----------------------------------------------------------------------------------------*/
+
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+int cv2Mat(const cv::Mat mat, Mat<T>* red, Mat<T>* green, Mat<T>* blue)
+{
+    int r = mat.rows;
+    int c = mat.cols;
+    *red = Mat<T>((T)0, r,c);
+    *green = Mat<T>((T)0, r,c);
+    *blue = Mat<T>((T)0, r,c);
+
+    for(int x=0;x<=r;x++)
+    {
+            for(int y=0;y<=c;y++)
+            {
+                    red->set( mat.data[mat.step*y+x+0], x+1, y+1);
+                    green->set( mat.data[mat.step*y+x+1], x+1, y+1);
+                    blue->set( mat.data[mat.step*y+x+2], x+1, y+1);
+            }
+    }
+
+    return 1;
+}
+
+template<typename T>    //pas de point virgule en fin de ligne...
+int cv2MatAt(const cv::Mat mat, Mat<T>* red, Mat<T>* green, Mat<T>* blue)
+{
+    int r = mat.rows;
+    int c = mat.cols;
+    *red = Mat<T>((T)0, r,c);
+    *green = Mat<T>((T)0, r,c);
+    *blue = Mat<T>((T)0, r,c);
+
+    for(int x=0;x<=r;x++)
+    {
+            for(int y=0;y<=c;y++)
+            {
+                    red->set( mat.at<cv::Vec3b>(x,y)[0], x+1, y+1);
+                    green->set( mat.at<cv::Vec3b>(x,y)[1], x+1, y+1);
+                    blue->set( mat.at<cv::Vec3b>(x,y)[2], x+1, y+1);
+            }
+    }
+
+    return 1;
+}
+
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2cv(Mat<T> r, Mat<T> g, Mat<T> b)
+{
+    int rl = r.getLine();
+    int rc = r.getColumn();
+
+    int gl = g.getLine();
+    int gc = g.getColumn();
+
+    int bl = b.getLine();
+    int bc = b.getColumn();
+
+    cv::Mat rim( rl, rc, CV_8UC3);
+
+    if(rl==gl && gl==bl && rc==gc && gc==bc)
+    {
+        cout << "Creating cv::Mat..." << endl;
+        for(int x=0;x<=rl-1;x++)
+        {
+                for(int y=0;y<=rc-1;y++)
+                {
+                        rim.data[rim.step*y+x+0] = (uchar)r.get( x+1, y+1);
+                        rim.data[rim.step*y+x+1] = (uchar)g.get( x+1, y+1);
+                        rim.data[rim.step*y+x+2] = (uchar)b.get( x+1, y+1);
+                }
+        }
+        cout << "Creation cv::Mat : DONE." << endl;
+    }
+    else
+        rim = cv::Mat(1,1, CV_8UC3);
+
+    return rim;
+
+}
+
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2cvVec(Mat<T> r, Mat<T> g, Mat<T> b)
+{
+    int rl = r.getLine();
+    int rc = r.getColumn();
+
+    int gl = g.getLine();
+    int gc = g.getColumn();
+
+    int bl = b.getLine();
+    int bc = b.getColumn();
+
+    cv::Mat rim( rl, rc, CV_8UC3);
+
+    if(rl==gl && gl==bl && rc==gc && gc==bc)
+    {
+        cout << "Creating cv::Mat..." << endl;
+        cv::Mat_<cv::Vec3b>::const_iterator it = rim.begin<cv::Vec3b>();
+        cv::Mat_<cv::Vec3b>::const_iterator itend = rim.end<cv::Vec3b>();
+
+        int i = 0;
+        int j = 0;
+
+        for( ; it != itend; ++it)
+        {
+            *it= cv::Vec3b( r.get(i+1,j+1), g.get(i+1,j+1), b.get(i+1,j+1));
+
+            i++;
+            if( !(i+1)%rl)
+            {
+                i=0;
+                j++;
+            }
+        }
+        cout << "Creation cv::Mat : DONE." << endl;
+    }
+    else
+        rim = cv::Mat(1,1, CV_8UC3);
+
+    return rim;
+
+}
+
+
+template<typename T>    //pas de point virgule en fin de ligne...
+cv::Mat Mat2cvAt(Mat<T> r, Mat<T> g, Mat<T> b)
+{
+    int rl = r.getLine();
+    int rc = r.getColumn();
+
+    int gl = g.getLine();
+    int gc = g.getColumn();
+
+    int bl = b.getLine();
+    int bc = b.getColumn();
+
+    cv::Mat rim( rl, rc, CV_8UC3);
+
+    if(rl==gl && gl==bl && rc==gc && gc==bc)
+    {
+        cout << "Creating cv::Mat..." << endl;
+        for(int x=0;x<=rl-1;x++)
+        {
+                for(int y=0;y<=rc-1;y++)
+                {
+                        rim.at<cv::Vec3b>(x,y) = cv::Vec3b( r.get(x+1,y+1), g.get(x+1,y+1), b.get(x+1,y+1));
+                }
+        }
+        cout << "Creation cv::Mat : DONE." << endl;
+    }
+    else
+        rim = cv::Mat(1,1, CV_8UC3);
+
+    return rim;
+
+}
+
+
+#endif
+
+
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+
+
+/*GaussJordan.cpp templated*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> gaussTrans( Mat<T> C, int k);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> hhTrans( Mat<T> x);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> hhTransMat( Mat<T> A, int k);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> WielandHotellingTrans( Mat<T> A, Mat<T> eigv, T sigma, Mat<T> z);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T RayleighQuotient(Mat<T> A, Mat<T> q);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> gaussj( Mat<T>* A_, Mat<T>* b_, int method = 1);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> invSVD(const Mat<T> mat);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Normalization(Mat<T> A, int method = 2);
+template<typename T>
+Mat<T> computeSmallestNonZeroEig(Mat<T> A, T* eigval = NULL);
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> invGJ(const Mat<T> mat, int method = 1);
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T fabs_(T a)
+{
+    T r = a;
+
+    if(r<= (T)0)
+        r = -a;
+
+    return r;
+}
+
+
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*---------------------------------------------*/
+
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*Norme 1 naturelle*/
+T norme1( Mat<T> X)
+{
+    T r = 0;
+    int n = X.getLine();
+
+    for(int i=1;i<=n;i++)
+    {
+        r += abs(X.get(i,1));
+    }
+    
+
+    return r;
+}
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*Norme 2 naturelle*/
+T norme2( Mat<T> X)
+{
+    T r = 0;
+    int n = X.getLine();
+
+    for(int i=1;i<=n;i++)
+    {
+        r += X.get(i,1)*X.get(i,1);
+    }
+
+    r = sqrt(r);
+
+    return r;
+}
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*Gauss transformation computing :
+ * C : column matrix which corresponds to the column of the matrix that we want to zero from the k+1-th element to the end.
+ * k : index of the element that is to be used as a pivot.
+ */
+Mat<T> gaussTrans( Mat<T> C, int k)
+{
+    if(k >= 1 && k<= C.getLine())
+    {
+        int n = C.getLine();
+        Mat<T> M( 0, n,n);
+
+        for(int i=1;i<=n;i++)   M.set((T)1, i,i);
+
+
+        if(C.get(k,1) != 0)
+        {
+            T ipiv = 1.0/C.get(k,1);
+
+            for(int i=k+1;i<=n;i++) M.set( -C.get(i,1)*ipiv, i,k);
+        }
+        else    throw("ERREUR : gauss transformation : le pivot fourni est nul.");
+
+        return M;
+    }
+    else    throw("ERREUR: mauvais parametre pour la transformation de gauss.");
+
+    return Mat<T>( (T)0, 1, 1);
+}
+
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> hhTrans( Mat<T> x)
+{
+    int n = x.getLine();
+    Mat<T> H((T)0, n,n);
+        
+    Mat<T> temp(transpose( extract(x, 2,1, n,1)));    
+    temp = temp*extract(x, 2,1, n,1);    
+    T sigma = temp.get(1,1);
+    Mat<T> v( extract(x, 2,1, n,1), (T)1, 2, 1,  n, 1);
+    T beta = 0;
+    
+    if(sigma != (T)0)
+    {
+        T mu = sqrt(x.get(1,1)*x.get(1,1)+sigma);
+
+        if(x.get(1,1) <= (T)0)
+            v.set( x.get(1,1) - mu, 1,1);
+        else
+            v.set( -sigma/(x.get(1,1) + mu), 1,1);
+        
+        beta = 2*v.get(1,1)*v.get(1,1)/(sigma + v.get(1,1)*v.get(1,1));        
+        v = ((T)(1/v.get(1,1)))*v;
+
+    }
+    
+    for(int i=1;i<=n;i++)   H.set( (T)1, i,i);
+
+    temp = beta*v;        
+    Mat<T> temp1(transpose(v));    
+    temp = temp*temp1;    
+    H = H - temp;        
+
+    return H;
+
+}
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*Householder transformation computing :
+ * A : matrix whose k-th column corresponds to the column of the matrix that we want to zero from the k+1-th element to the end.
+ * k : index of the element that is to be used as a pivot.
+ */
+Mat<T> hhTransMat( Mat<T> A, int k)
+{
+    int n = A.getLine();
+    //int m = A.getColumn();
+    Mat<T> H( hhTrans( extract( A, k,k, n, k ) ), (T)0, k, k, n, n );
+    /*hhTrans renvoie une matrice de la taille n-k+1 x n-k+1 )*/
+
+    for(int i=1; i<=k-1;i++)    H.set( (T)1, i, i);
+
+    return H;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*Wieland's hotelling transformation computing : returns the shifted matrix.
+ * A : matrix whose  eigv associated eigenvalue will be shifted with regards to sigma : eigvValue := eigvValue - sigma.
+ * eigv : eigenvectors whose assiocated eigenvalue will be shifted.
+ * sigma : linear shifting value.
+ * z : vectors which have an influence of the shifting of the right eigenvectors : rEigv := rEigv - gamma*eigv / gamma = sigma*(z.H*eigv)/(sigma - (eigvValue - rEigvValue)).
+ */
+Mat<T> WielandHotellingTrans( Mat<T> A, Mat<T> eigv, T sigma, Mat<T> z)
+{
+    Mat<T> r(A);
+    
+    if(eigv.getLine() == z.getLine() && eigv.getLine() == A.getLine() && A.getLine() == A.getColumn())
+    {
+        r = A - sigma*(eigv*transpose(z));
+        //it should be the hermitian conjugate but for now on we only deal with real matrices so...
+    }
+    else
+        cerr << "PROBLEM : Wieland Hotelling Transformation...." << endl;
+    
+    return r;
+}
+
+
+/*---------------------------------------------*/
+
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+T RayleighQuotient(Mat<T> A, Mat<T> q)
+{
+    T r=0;
+    
+    if(A.getLine()==A.getColumn() && A.getLine()==q.getLine())
+    {
+        T temp = (transpose(q)*q).get(1,1); // it should be a hermitian conjugate...
+        
+        if(temp != (T)0)
+            r = (T) ((transpose(q)*A*q).get(1,1) / temp);
+        else
+            cerr << "PROBLEM : RAYLEIGHT QUOTIENT / 2" << endl;
+    }
+    else
+        cerr << "PROBLEM : RAYLEIGHT QUOTIENT / 1" << endl; 
+
+    return r;
+}
+
+
+
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*Perform Gauss Jordan Elimanation (1)full-pivoting (2)with backsubstitution : */
+Mat<T> gaussj( Mat<T>* A_, Mat<T>* b_, int method)
+{
+    if( A_ != NULL && b_ != NULL)
+    {
+        Mat<T> A(*A_), b(*b_);
+        
+        /*bool diag = true;
+        for(int i=A.getLine();i--;)
+        {
+            for(int j=A.getColumn();j--;)
+            {
+                if(i!=j)
+                {
+                    if(A.get(i,j) != (T)0)
+                    {
+                        diag=false;
+                        i=0;
+                    }
+                }
+            }
+        }
+        if(diag)
+        {
+                
+        }*/
+
+        switch(method)
+        {
+            case 1 :
+            {
+            /* Full-Pivoting */
+            int n, m;
+            n = A.getLine();
+            m = b.getColumn();
+            T big=0, pivinv=0;                        
+
+            /*bookkeeping */
+            int irow=1, icol=1;
+            Mat<T> indxc(n, 1);
+            Mat<T> indxr( n,1);
+            Mat<T> ipiv((T)0, n,1);                        
+
+            #ifdef verbose
+            cout << "matrice originale :" << endl;
+            A.afficher();
+            #endif
+
+            Mat<T> I( (T)0, n,n);
+            for(int i=1;i<=n;i++)
+                I.set((T)1, i,i);
+                            
+
+            for(int i=1;i<=n;i++)
+            {
+                big = 0.0;
+                for(int j=1;j<=n;j++)
+                {
+                    if(ipiv.get(j,1) != (T)1)   /*si cette ligne j ne contient pas deja un pivot... */
+                    {
+                        for(int k=1;k<=n;k++)
+                        {
+                            if(ipiv.get(k,1) == 0) /* si cette ligne k ne contient pas deja un pivot..*/
+                            {
+                                if(fabs_(A.get(j,k)) > big)
+                                {
+                                    big = fabs_(A.get(j,k));
+                                    irow = j;
+                                    icol = k;
+                                }
+
+                            }
+                        }
+
+                    }
+                }
+                ipiv.set(ipiv.get(icol,1)+1, icol,1);
+                /*on a bien un pivot à la icol ligne, car c'est la valeur la plus grande de */                                
+
+                /*Maintenant que l'on a le pivot, il faut le mettre sur la diagonale en interchangeant les colonnes
+                 * --> b doit changer de la meme manière que A ; l'inverse obtenue devra etre changee.
+                 */
+
+                indxr.set((T)irow, i,1) ;
+                indxc.set((T)icol, i,1);
+                if(irow != icol)
+                {
+                    for(int l=1;l<=n;l++)   A.swap( irow, l, icol, l);
+                    for(int l=1;l<=n;l++)   I.swap( irow, l, icol, l);
+                    for(int l=1;l<=m;l++)   b.swap( irow, l, icol, l);
+                }                                
+
+                /*on peut maintenant faire les divisions et soustractions qui vont bien. */
+                if(A.get(icol,icol) == (T)0)
+                {
+                    //cerr << "Singular Matrix : diag element : " << i << endl;
+                    pcm.printf("Singular Matrix : diag element : %d\n", i);
+                    A.afficherM();
+                    //throw("Singular Matrix...");
+                    A.set( numeric_limits<T>::epsilon(), icol, icol);
+                }                                
+
+                pivinv = 1.0/A.get(icol,icol);
+                for(int l=1;l<=n;l++)   A.set(A.get(icol,l)*pivinv, icol, l);
+                for(int l=1;l<=n;l++)   I.set(I.get(icol,l)*pivinv, icol, l);
+                for(int l=1;l<=m;l++)   b.set(b.get(icol,l)*pivinv, icol, l);
+
+                for(int ll=1;ll<=n;ll++)
+                {
+                    if(ll != icol)
+                    {
+                        T dum = A.get(ll, icol);
+                        /*A.set((T)0, ll, icol);*/
+                        /*il semble que cette opération soit bien faite
+                         * dans la boucle for qui suit.... ?
+                         */
+                        for(int l=1;l<=n;l++)   A.set( A.get(ll,l)-dum*A.get(icol,l), ll, l);
+                        for(int l=1;l<=n;l++)   I.set( I.get(ll,l)-dum*I.get(icol,l), ll, l);
+                        for(int l=1;l<=m;l++)   b.set( b.get(ll,l)-dum*b.get(icol,l), ll, l);
+
+                    }
+                }                                
+
+                #ifdef verbose
+                cout << "Step : " << i << endl;
+                A.afficher();
+                I.afficher();
+                #endif
+
+            }
+
+/*-------------------------------------------------------------------------------------------------------------------*/
+            /*unscrabling of the solution in view of the column interchanges by interchanging pairs of columns
+             *in the reverse order of their permutation during the algorithm above :
+             */
+            /*
+
+            for(int l=n;l>=1;l--)
+            {
+                //if the former indexes of the l-th pivot element were not the same
+                //then permutations have ensuied and thus we have to reverse them.
+                //
+                if(indxr.get(l,1) != indxc.get(l,1))
+                {
+                    //we swap the indxr[l]-th column with the indxc[l]-th one.
+                    for(int k=1;k<=n;k++)   A.swap(k, indxr.get(l,1), k, indxc.get(l,1));
+                    for(int k=1;k<=n;k++)   I.swap(k, indxr.get(l,1), k, indxc.get(l,1));
+                }
+            }
+        */
+/*------------------------------------------------------------------------------------------------------------*/
+            /*------------------------------------*/
+            /*construction de la matrice inverse avec un produit de matrice C*/
+            /*-----------------------------------*/
+            /*matrices C*/
+
+            Mat<T>** C = NULL;
+            C = new Mat<T>*[n];            
+            
+            for(int i=0;i<=n-1;i++)
+            {
+                C[i] = new Mat<T>((T)0, n, n);
+
+                C[i]->set( (T)1, indxr.get(i+1,1), indxc.get(i+1,1));
+                C[i]->set( (T)1, indxc.get(i+1,1), indxr.get(i+1,1));
+
+                for(int ii=1;ii<=n;ii++)
+                    if(ii != indxc.get(i+1,1) && ii!=indxr.get(i+1,1))
+                        C[i]->set((T)1, ii, ii);
+
+                #ifdef verbose
+                cout << "C : " << i << " : avec (i,j) pivot : (" << indxr.get(i+1,1) << "," << indxc.get(i+1,1) << ")" << endl;
+                C[i]->afficher();
+                #endif
+            }                        
+
+            Mat<T> Ai(*C[0]);            
+            for(int i=1;i<=n-1;i++)
+            {
+                //Ai.afficherM();
+                //C[i]->afficherM();
+                Ai = Ai*(*C[i]);
+                //Ai.afficherM();
+                //pcm.printf("10 : %d\n",i);
+            }
+                
+            
+
+            /*-------------------------------*/
+
+            for(int i=0;i<=n-1;i++)
+                delete C[i];
+            delete[] C;
+
+            /*------------------------------------*/
+
+            *A_ = I;
+            *b_ = b;                                    
+
+            return Ai;
+
+            }
+
+
+            case 2 :
+            /* backsubstitution : triangular decomposition */
+
+            {
+            /* Full-Pivoting */
+            int n, m;
+            n = A.getLine();
+            m = b.getColumn();
+            T big, pivinv;
+
+            /*bookkeeping */
+            int irow=0, icol=0;
+            Mat<T> indxc( n, 1);
+            Mat<T> indxr( n,1);
+            //Mat<T> ipiv((T)0, n,1);
+
+            #ifdef verbose
+            cout << "matrice originale :" << endl;
+            A.afficher();
+            #endif
+            Mat<T> I( (T)0, n,n);
+            for(int i=1;i<=n;i++)
+                I.set((T)1, i,i);
+
+            for(int i=1;i<=n;i++)
+            {
+                big = 0.0;
+                for(int j=1;j<=n;j++)
+                {
+                    //if(ipiv.get(j,1) != (T)1) /*si cette ligne j ne contient pas deja un pivot... */
+                    //{
+                        //for(int k=1;k<=n;k++)
+                        //{
+                            //if(ipiv.get(k,1) == 0) /* si cette ligne k ne contient pas deja un pivot..*/
+                            //{
+                                if(fabs_(A.get(i,j)) > big)
+                                {
+                                    big = fabs_(A.get(i,j));
+                                    irow = i;
+                                    icol = j;
+                                }
+
+                            //}
+                        //}
+
+                    //}
+                }
+                //ipiv.set(ipiv.get(icol,1)+1, icol,1);
+                /*on a bien un pivot à la irow ligne, car c'est la valeur la plus grande de la colonne i*/
+
+                /*Maintenant que l'on a le pivot, il faut le mettre sur la diagonale en interchangeant les lignes
+                 * --> b doit changer de la meme manière que A ; l'inverse obtenue devra etre changee.
+                 */
+
+                indxr.set((T)irow, i,1) ;
+                indxc.set((T)icol, i,1);
+                if(irow != icol)
+                {
+                    for(int l=1;l<=n;l++)   A.swap( irow, l, icol,l);
+                    for(int l=1;l<=n;l++)   I.swap( irow, l, icol,l);
+                    for(int l=1;l<=m;l++)   b.swap( irow, l, icol,l);// attention a l'indice et sa limite.
+                }
+                /*echange des lignes et non des colonnes.*/
+                /*du coup il faut faire le changement juste après de icol --> irow car le pivot est en irow,irow !*/
+
+                /*on peut maintenant faire les divisions et soustractions qui vont bien. */
+                if(A.get(irow,irow) == 0.0)
+                {
+                    //throw("Singular Matrix...");
+                    A.set( numeric_limits<T>::epsilon(), irow, irow);
+                }
+
+                pivinv = 1.0/A.get(irow,irow);
+                for(int l=1;l<=n;l++)   A.set(A.get(irow,l)*pivinv, irow, l);
+                for(int l=1;l<=n;l++)   I.set(I.get(irow,l)*pivinv, irow, l);
+                for(int l=1;l<=m;l++)   b.set(b.get(irow,l)*pivinv, irow, l);
+
+                for(int ll=1;ll<=n;ll++)
+                {
+                    if(ll > irow)   //petit changement, != --> > de sorte que l'on ne change que les lignes en dessous de la position du pivot du moment.
+                    {
+                        T dum = A.get(ll, irow);
+                        /*A.set((T)0, ll, icol);*/
+                        /*il semble que cette opération soit bien faite
+                         * dans la boucle for qui suit.... ?
+                         */
+                        for(int l=1;l<=n;l++)   A.set( A.get(ll,l)-dum*A.get(irow,l), ll, l);
+                        for(int l=1;l<=n;l++)   I.set( I.get(ll,l)-dum*I.get(irow,l), ll, l);
+                        for(int l=1;l<=m;l++)   b.set( b.get(ll,l)-dum*b.get(irow,l), ll, l);
+
+                    }
+                }
+
+                #ifdef verbose
+                cout << "Step : " << i << endl;
+                A.afficher();
+                I.afficher();
+                #endif
+
+                if(i==n)
+                    (I.getInv()).afficher();
+
+            }
+
+
+            /*------------------------------------*/
+            /*construction de la matrice inverse avec un produit de matrice C*/
+            /*-----------------------------------*/
+            /*matrices C*/
+
+            Mat<T>** C = NULL;
+            C = new Mat<T>*[n];
+
+            for(int i=0;i<=n-1;i++)
+            {
+                C[i] = new Mat<T>( (T)0, n, n);
+
+                C[i]->set( (T)1, indxr.get(i+1,1), indxc.get(i+1,1));
+                C[i]->set( (T)1, indxc.get(i+1,1), indxr.get(i+1,1));
+
+                for(int ii=1;ii<=n;ii++)
+                    if(ii != indxc.get(i+1,1) && ii!=indxr.get(i+1,1))
+                        C[i]->set((T)1, ii, ii);
+
+                #ifdef verbose
+                cout << "C : " << i << " : avec (i,j) pivot : (" << indxr.get(i+1,1) << "," << indxc.get(i+1,1) << ")" << endl;
+                C[i]->afficher();
+                #endif
+            }
+
+            Mat<T> Ai(*C[n-1]);
+            for(int i=n-2;i>=0;i--)
+                Ai = Ai*(*C[i]);
+
+            /*-------------------------------*/
+
+            for(int i=0;i<=n-1;i++)
+                delete C[i];
+            delete C;
+
+            /*------------------------------------*/
+            /*------------------------------------*/
+            /*------------------------------------*/
+            /* BACKSUBSTITUTION */
+            /*------------------------------------*/
+            /*------------------------------------*/
+            /*------------------------------------*/
+
+
+            Mat<T> X(b);
+
+            for(int j=1;j<=m;j++)
+            {
+                /*pour chaque colonne de b :*/
+                for(int i=n;i>=1;i--)
+                {
+                    /*backsubstitution*/
+                    T temp = 0;
+                    T inv = 1.0/A.get(i,i);
+                    for(int ii=i+1;ii<=n;ii++)
+                        temp += A.get(ii,i)*X.get(ii,j);
+                    X.set( inv*(b.get(i,j) - temp), i,j);
+                }
+
+            }
+
+            /*-----------------------------------*/
+            /*
+            //unscrabling of the solution in view of the row interchanges by interchanging pairs of rows
+            // in the reverse order of their permutation during the algorithm above :
+
+
+            for(int l=n;l>=1;l--)
+            {
+                //if the former indexes of the l-th pivot element were not the same
+                //then permutations have ensuied and thus we have to reverse them.
+                //
+                if(indxr.get(l,1) != indxc.get(l,1))
+                {
+                    //we swap the indxr[l]-th line with the indxc[l]-th one.*/ /*on parle bien de ligne cette fois...
+                    for(int k=1;k<=n;k++)   A.swap( indxr.get(l,1), k, indxc.get(l,1), k);
+                    for(int k=1;k<=n;k++)   I.swap( indxr.get(l,1), k, indxc.get(l,1), k);
+                }
+            }
+            */
+            /*------------------------------------*/
+
+            *A_ = A;
+            *b_ = b;
+
+
+            return X;
+
+            }
+
+            default :
+            throw("Mauvaise valeur de method.");
+            break;
+        }
+
+
+    }
+    else
+        throw("Pointeurs arguments non-initializes.");
+
+    return *A_;
+}
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> Normalization(Mat<T> A, int method)
+{
+
+    T (*ptrnorme)(Mat<T>) = NULL;
+    ptrnorme = norme2;
+    if( method == 1)
+        ptrnorme = norme1;
+        
+    int n = A.getColumn();
+    Mat<T> I( (T)0, n,n);
+    for(int i=1;i<=n;i++)
+    {
+        I.set((T)1, i,i);
+    }
+
+    Mat<T>* B = new Mat<T>();
+
+    bool init = false;
+    for(int it=1;it<=n;it++)
+    {
+        if(ptrnorme( Cola(A,it) ) != (T)0)
+        {
+            if(!init)
+            {
+                *B = ((T)(1./(T)ptrnorme( Cola(A,it) ) )) * Cola(A,it);
+                init = true;
+            }
+            else
+            {
+                *B = operatorL( *B, ((T)(1./(T)ptrnorme( Cola(A,it) ) )) * Cola(A, it) );
+            }
+        }
+        else
+        {
+            if(!init)
+            {
+                *B = ((T)0)*Cola(A, it);
+                init = true;
+            }
+            else
+            {
+                *B = operatorL( *B, ((T)0)*Cola(A, it) );
+            }
+        }
+
+        /*-----------------------*/
+        /*
+        cout << "Step :" << it << " avec 1/norme(X) : " << 1/ptrnorme(Cola(A,it)) << endl;
+        A.afficher();
+        T->afficher();
+        */
+        /*--------------------------*/
+
+    }
+
+    Mat<T> r(*B);
+    delete B;
+
+
+    return r;
+}
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> invGJ(const Mat<T> mat, int method)
+{
+    Mat<T> r(mat);
+    Mat<T> b((T)0, r.getLine(), 1);    
+    gaussj(&r,&b, method);
+    
+    return r;
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+class LU
+{
+
+private :
+
+    int n;
+    int nbrM;
+    Mat<T>* L_;
+    Mat<T>* U_;
+    Mat<T>* A_;
+    Mat<T>** M;
+
+public :
+
+    /*LU decomposition :
+     * A : matrix to be decomposed.
+     * L : pointer initialized at NULL that is to be allocated and filled up with the L matrix by the function.
+     * U : pointer initialized at NULL that is to be allocated and filled up with the U matrix by the function.
+     */
+    LU(Mat<T> A, Mat<T>* L, Mat<T>* U)
+    {
+        A_ = new Mat<T>(A);
+        n = A.getColumn();
+        nbrM = (n<= A.getLine() ? n : A.getLine());
+        //M = (Mat<T>**)malloc(sizeof(Mat<T>*)*(nbrM-1));
+        M = new Mat<T>*[nbrM-1];
+        L_ = NULL;
+        U_ = NULL;
+
+        if(L != NULL || U != NULL)  throw("ERREUR : LU decomposition : mauvais pointeurs de matrices L et/ou U.");
+
+        //L =(Mat<T>*)malloc(sizeof(Mat<T>));
+        //*L = Mat<T>( (T)0, A.getLine(), A.getLine());
+        L = new Mat<T>( (T)0, A.getLine(), A.getLine());
+        for(int i=1;i<=L->getLine();i++)    L->set( (T)1, i,i);
+        //U = (Mat<T>*)malloc(sizeof(Mat<T>));
+        //*U = Mat<T>(A);
+        U = new Mat<T>(A);
+
+
+
+        for(int i=1;i<= nbrM-1;i++)
+        {
+            M[i-1] = new Mat<T>(gaussTrans( Col(*U, i), i));
+            *U = (*M[i-1])*(*U);
+
+            cout << "Step " << i << " : " << endl;
+            M[i-1]->afficher();
+            U->afficher();
+
+            Mat<T> invM(M[i-1]->getInv());
+            *L = (*L)*invM;
+        }
+
+        cout << "L" << endl;
+        L->afficher();
+
+        cout << "U" << endl;
+        U->afficher();
+
+        cout << " Produit " << endl;
+        ((*L)*(*U)).afficher();
+
+        L_ = new Mat<T>(*L);
+        U_ = new Mat<T>(*U);
+
+
+    }
+
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+
+    /*LU decomposition :
+     * A : matrix to be decomposed.
+     */
+    LU(Mat<T> A)
+    {
+        A_ = new Mat<T>(A);
+        n = A.getColumn();
+        nbrM = (n<= A.getLine() ? n-1 : A.getLine()-1);
+        //M = (Mat<T>**)malloc(sizeof(Mat<T>*)*(nbrM-1));
+        M = new Mat<T>*[nbrM-1];
+
+
+        //L_ =(Mat<T>*)malloc(sizeof(Mat<T>));
+        //*L_ = Mat<T>((T)0, A.getLine(), A.getLine());
+        L_ = new Mat<T>( (T)0, A.getLine(), A.getLine());
+        for(int i=1;i<=L_->getLine();i++)   L_->set( (T)1, i,i);
+        //U_ = (Mat<T>*)malloc(sizeof(Mat<T>));
+        //*U_ = Mat<T>(A);
+        U_ = new Mat<T>(A);
+
+        for(int i=1;i<=nbrM-1;i++)
+        {
+            M[i-1] = new Mat<T>(gaussTrans( Col(*U_, i), i));
+            *U_ = (*M[i-1])*(*U_);
+
+            //cout << "Step " << i << " : " << endl;
+            //M[i-1]->afficher();
+            //U_->afficher();
+
+            Mat<T> invM(M[i-1]->getInv());
+            *L_ = (*L_)*invM;
+        }
+    }
+
+
+
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+
+
+
+    ~LU()
+    {
+        for(int i=0; i<=nbrM-2;i++) delete M[i];
+        delete M;
+
+        if( L_ != NULL) delete L_;
+        if( U_ != NULL) delete U_;
+        if( A_ != NULL) delete A_;
+
+        cout << "LU : exited cleanly." << endl;
+    }
+
+
+
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+
+    Mat<T> getL() const
+    {
+        return *L_;
+    }
+
+    Mat<T> getU() const
+    {
+        return *U_;
+    }
+
+
+};
+
+
+
+
+/*---------------------------------------------*/
+/*---------------------------------------------*/
+/*---------------------------------------------*/
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+class QR
+{
+
+private :
+
+    int n;
+    int nbrM;
+    Mat<T>* Q_;
+    Mat<T>* R_;
+    Mat<T>* A_;
+    Mat<T>** M;
+
+public :
+
+    /*QR decomposition :
+     * A : matrix to be decomposed.
+     * Q : pointer initialized at NULL that is to be allocated and filled up with the Q matrix by the function.
+     * R : pointer initialized at NULL that is to be allocated and filled up with the R matrix by the function.
+     */
+    QR(Mat<T> A, Mat<T>* Q, Mat<T>* R)
+    {
+        A_ = new Mat<T>(A);
+        n = A.getColumn();
+        
+        if(n<= A.getLine() )
+            nbrM = n;
+        else
+            nbrM = A.getLine();
+                    
+        //M = (Mat<T>**)malloc(sizeof(Mat<T>*)*(nbrM-1));
+        M = new Mat<T>*[nbrM-1];
+        Q_ = NULL;
+        R_ = NULL;
+
+        if(Q != NULL || R != NULL)  throw("ERREUR : QR decomposition : mauvais pointeurs de matrices L et/ou U.");
+
+        //Q =(Mat<T>*)malloc(sizeof(Mat<T>));
+        //*Q = Mat<T>((T)0, A.getLine(),A.getLine());
+        Q = new Mat<T>( (T)0, A.getLine(),A.getLine());
+        for(int i=1;i<=Q->getLine();i++)    Q->set( (T)1, i,i);
+        //R = (Mat<T>*)malloc(sizeof(Mat<T>));
+        //*R = Mat<T>(A);
+        R = new Mat<T>(A);
+
+
+        for(int i=1;i<=nbrM-1;i++)
+        {
+            M[i-1] = new Mat<T>( hhTransMat( *R, i));
+            *R = (*M[i-1])*(*R);
+
+            //cout << "Step " << i << " : " << endl;
+            //M[i-1]->afficher();
+           // R->afficher();
+
+            Mat<T> invM(transpose(*M[i-1]) );//M[i-1]->getInv());
+            *Q = (*Q)*invM;
+        }
+        
+        /*
+        pcm.printf( "Q : \n");
+        Q->afficherM();
+
+        pcm.printf("R : \n");
+        R->afficherM();
+
+        pcm.printf(" Produit \n");
+        ((*Q)*(*R)).afficherM();
+        */
+
+        Q_ = new Mat<T>(*Q);
+        R_ = new Mat<T>(*R);
+
+
+    }
+
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+
+    /*QR decomposition :
+     * A : matrix to be decomposed.
+     */
+    QR(Mat<T> A)
+    {
+        A_ = new Mat<T>(A);
+        n = A.getColumn();
+        
+        if(n<= A.getLine() )
+            nbrM = n;
+        else
+            nbrM = A.getLine();
+            
+        M = new Mat<T>*[nbrM-1];
+
+
+        Q_ = new Mat<T>( (T)0, A.getLine(), A.getLine() );
+        for(int i=1;i<=Q_->getLine();i++)   Q_->set( (T)1, i,i);
+        R_ = new Mat<T>(*A_);        
+        
+        for(int i=1;i<=nbrM-1;i++)
+        {            
+            
+            M[i-1] = new Mat<T>( hhTransMat( *R_, i));
+            *R_ = (*M[i-1])*(*R_);
+            
+            #ifdef verbose
+            cout << "Step " << i << " : " << endl;
+            M[i-1]->afficher();
+            R_->afficher();
+            cout << "Inversion ..." << endl;
+            #endif
+
+
+            //Mat<T> invM(M[i-1]->getInv());            
+            Mat<T> invM(transpose(*M[i-1]) );
+            /*Mat<T> b( (T)0, invM.getLine(), 1);
+            pcm.printf("qr : i = %d / %d\n",i, nbrM-1);
+            gaussj(&invM, &b, 1);*/            
+            // IL Y A N GROS PROBLEME : les verifications des produits ne fonctionnent pas avec cette méthode....
+            #ifdef verbose
+            invM.afficher();
+            #endif
+            *Q_ = (*Q_)*invM;
+        }
+                
+    }
+
+
+
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+
+
+
+    ~QR()
+    {
+        for(int i=0; i<=nbrM-2;i++) delete M[i];
+        delete M;
+
+        if( Q_ != NULL) delete Q_;
+        if( R_ != NULL) delete R_;
+        if( A_ != NULL) delete A_;
+
+        cout << "QR : exited cleanly." << endl;
+    }
+
+
+
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+    /*----------------------------------*/
+
+    Mat<T> getQ() const
+    {
+        return *Q_;
+    }
+
+    Mat<T> getR() const
+    {
+        return *R_;
+    }
+
+
+};
+
+
+
+
+
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+class SVD
+{
+
+    private :
+
+    Mat<T>* A_;
+    QR<T>* qr1;
+    QR<T>* qr;
+    Mat<T>* U;
+    Mat<T>* S;
+    Mat<T>* V;
+
+    public :
+
+    SVD(Mat<T> A, int iteration = 100)
+    {
+        /* QR decomposition */        
+        qr1 = new QR<T>(A);
+        Mat<T> Q1(qr1->getQ());
+        Mat<T> R1(qr1->getR());
+        
+#ifdef verbose
+        cout << "//////////////////////////////" << endl;
+        cout << "Matrice Q1 : " << endl;
+        Q1.afficher();
+        cout << "Matrice R1 : " << endl;
+        R1.afficher();
+        /*-------------------*/
+
+        cout << endl << "Decomposition QR : DONE !!!" << endl << endl;
+#endif
+        /* QR decomposition of R1 */        
+        qr = new QR<T>(transpose(R1));
+        Mat<T> Q(qr->getQ());
+        Mat<T> R(qr->getR());        
+#ifdef verbose
+        //cout << "Matrice Q : " << endl;
+        //Q.afficherM();
+        //cout << "Matrice R : " << endl;
+        //R.afficherM();
+        /*---------------------*/        
+
+        //cout << endl << "Decomposition QR de R.t : DONE !!!" << endl << endl;
+
+        //cout << "Verification : " << endl;
+        //pcm.printf("Matrice A : \n");
+        //A.afficherM();
+        //cout << "Produit : " << endl;
+        //(Q1*transpose(R)*transpose(Q)).afficherM();
+        //cout << "Verification de l'orthogonalité de Q1 : " << endl;
+        //(Q1*transpose(Q1)).afficher();
+        //cout << "Verification de D : " << endl;
+        //transpose(R).afficherM();
+        //cout << "Verification de l'orthogonalité de Q : " << endl;
+        //(Q*transpose(Q)).afficher();                
+        
+        /*----------------------------------------*/        
+        /*----------------------------------------*/
+        /*----------------------------------------*/
+        cout << "ASSIGNATION ..." << endl;
+        R.afficher();
+#endif
+
+
+        Mat<T> D(transpose(R));
+        QR<T>* rec = new QR<T>(D);
+        Mat<T> Qr(rec->getQ());
+        Mat<T> rtemp(rec->getR());
+        delete rec;
+        rec = new QR<T>(transpose(rtemp));
+        Mat<T> tQl(transpose(rec->getQ()));
+        D = transpose( rec->getR());
+
+        Mat<T> error(D);
+        int dimmax;
+        if(error.getLine() > error.getColumn())
+            dimmax = error.getLine();
+        else
+            dimmax = error.getColumn();
+            
+                        
+        for(int i=1;i<= dimmax;i++) error.set((T)0, i,i);
+        T eps =  numeric_limits<T>::epsilon();
+
+        while( iteration >= 0 && sum(sum(error)).get(1,1) > eps*10e-2)
+        {
+            //cout << "Iteration : " << iteration-- << endl;
+            iteration--;
+            delete rec;
+            rec = new QR<T>(D);
+            Qr = Qr * rec->getQ();
+            rtemp = rec->getR();
+            delete rec;
+            rec = new QR<T>(transpose(rtemp));
+            tQl = transpose(rec->getQ()) * tQl;
+            D = transpose( rec->getR());
+#ifdef verbose
+            D.afficher();
+#endif
+
+            /////////////////
+            error = D;
+            if(error.getLine() > error.getColumn())
+                dimmax = error.getLine();
+            else
+                dimmax = error.getColumn();
+                
+            for(int i=1;i<= dimmax;i++) error.set((T)0, i,i);
+
+
+        }
+        delete rec;
+
+        Qr = Q1*Qr;
+        tQl = tQl*transpose(Q);
+
+#ifdef verbose
+        cout << "Methode itérative : " << endl;
+        cout << "Matrice originale :" << endl;
+        A.afficher();
+        cout << "Produit : " << endl;
+        (Qr*D*tQl).afficher();
+        cout << " U :" << endl;
+        Qr.afficher();
+        cout << " S :" << endl;
+        D.afficher();
+        cout << " V :" << endl;
+        transpose(tQl).afficher();
+#endif        
+        ///////////////////////////////////////////////////////////////
+    /*
+        A_ = new Mat<T>(A);
+        U = new Mat<T>(Q1);
+        S = new Mat<T>(transpose(R));
+        V = new Mat<T>(Q);
+        */
+        //cout << "Initialement : D vaut :" << endl;
+        transpose(R).afficherM();
+        
+        A_ = new Mat<T>(A);
+        U = new Mat<T>(Qr);
+        S = new Mat<T>(D);
+        V = new Mat<T>(transpose(tQl));
+
+        /*nettoyage */
+        /*rien... that's how the cookie crumble x) !! */
+
+    }
+
+    ~SVD()
+    {
+        delete A_;
+        delete qr1;
+        delete qr;
+        delete U;
+        delete S;
+        delete V;
+    }
+
+    Mat<T> getU() const
+    {
+        return *U;
+    }
+
+    Mat<T> getS() const
+    {
+        return *S;
+    }
+
+    Mat<T> getV() const
+    {
+        return *V;
+    }
+
+};
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> invSVD(const Mat<T> mat)
+{    
+    SVD<T> instance(mat);        
+    Mat<T> Si(instance.getS());
+            
+    for(int i=Si.getLine();i--;)
+    {
+        if(Si.get(i,i) != (T)0)
+            Si.set(1.0/Si.get(i,i), i,i);
+        else
+        {
+            Si.set( 1.0/numeric_limits<T>::epsilon(), i,i);    
+        }            
+    }
+    
+    Mat<T> ret(transpose(instance.getV()) );
+    ret = ret * Si;    
+    ret = ret * transpose( instance.getU() );
+    
+    return ret;
+}
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+class PIt   //Power iteration class : eigenvalues are the squared ones if the initial matrix is not a square matrix...
+        // Assuming that the eigenvalues are real and different from one to another...
+{
+
+    private :
+
+    int n;      //A square dimension.
+    Mat<T> A_;      // square matrix
+    Mat<T> leigvec;     //left eigenvectors.    column stack
+    Mat<T> reigvec; //right eigenvectors.   column stack
+    Mat<T> eigval;  //eigenvalues.  Column
+
+
+    int iteration;  //nbr of iteration for convergance...   default = 10;
+    
+    public :
+
+    PIt(Mat<T> A)
+    {        
+        n = A.getColumn();
+        A_ = (n==A.getLine() ? A : transpose(A)*A); //if the matrix is not square, we square it... dim : n x n.
+        
+        leigvec = Mat<T>((T)0, n, 1);
+        reigvec = Mat<T>((T)0, n, 1);
+        eigval = Mat<T>((T)0, 1,1);
+        
+        iteration = 100;
+        
+        /*Main loop*/
+        Mat<T> tempPoweredMat(A_);
+        Mat<T> initQ( Normalization( Mat<T>((T)1,n,1), 2)); //Euclidian normalization.
+        for(int i=1;i<=n;i++)
+        {
+            powerIt( tempPoweredMat, initQ, &reigvec, &leigvec, &eigval, iteration);
+            
+            tempPoweredMat = WielandHotellingTrans( tempPoweredMat, Cola(reigvec, i+1), eigval.get(i+1,1), Cola(leigvec, i+1) );
+            //watch out the offset...           
+        }
+        
+        /*-------------------------*/
+        
+        
+        /*remise en forme...*/
+        leigvec = extract(leigvec, 1,2, n,n+1);
+        reigvec = extract(reigvec, 1,2, n,n+1);
+        eigval = extract(eigval, 2,1, n+1,1);
+        
+    }
+
+    ~PIt()
+    {
+       
+    }
+    
+    
+    /*--------------------------------------------------------------------------*/
+    
+    
+    static void powerIt( Mat<T> tempPoweredMat, Mat<T> initQ, Mat<T>* reigvec, Mat<T>* leigvec, Mat<T>* eigval, int iteration)
+    {
+        Mat<T> A(tempPoweredMat);
+        Mat<T> ltemp(transpose(tempPoweredMat));
+        Mat<T> rq(initQ);   //already normalized.
+        Mat<T> lq(initQ);
+        
+        T eigv = 0;
+        
+        /*
+        for(int i=1;i<=iteration;i++)
+        {
+            rq = tempPoweredMat*rq;
+            rq = Normalization(rq, 2);
+            
+            lq = ltemp*lq;
+            lq = Normalization(lq, 2);
+        }
+        */
+        
+        T epsilon = (T)10e-4;
+    T lambdat = 0;
+    while( iteration-- != 0 && fabs_(eigv-lambdat) > epsilon)
+    {
+        lambdat = eigv;
+            rq = tempPoweredMat*rq;
+            rq = Normalization(rq, 2);
+            
+            lq = ltemp*lq;
+            lq = Normalization(lq, 2);
+            
+            //eigv = RayleighQuotient(A, rq);
+            eigv = norme2(A*rq)/norme2(rq);
+            
+            //cout << eigv << " et |lambdat - eigv| = " << fabs_(eigv-lambdat) << endl;
+        }
+    
+    
+        //eigv = RayleighQuotient(A, rq);
+        eigv = norme2(A*rq)/norme2(rq);
+        
+        /*ASSIGNATION*/
+        *eigval = operatorC(*eigval, Mat<T>((T)eigv, 1,1) );
+        *leigvec = operatorL(*leigvec, lq);
+        *reigvec = operatorL(*reigvec, rq);
+                    
+    }
+    
+    
+    /*---------------------------------------------------------------------------*/
+    /*---------------------------------------------------------------------------*/
+    /*---------------------------------------------------------------------------*/
+    /*---------------------------------------------------------------------------*/
+
+    Mat<T> getLeigvec() const
+    {
+        return leigvec;
+    }
+
+    Mat<T> getReigvec() const
+    {
+        return reigvec;
+    }
+
+    Mat<T> getEigval() const
+    {
+        return eigval;
+    }
+
+};
+
+
+template<typename T>
+Mat<T> computeSmallestNonZeroEig(Mat<T> A, T* eigval)
+{
+    PIt<T> instance(A);
+    Mat<T> eigv(instance.getEigval());
+    int dimin = eigv.getLine();
+    int idmin = 1;
+        T vmin = eigv.get(1,1);
+        
+        int i = 1;
+        while(vmin == (T)0)
+        {
+            i++;
+            vmin = eigv.get(i,1);
+        }
+        
+        T eps = numeric_limits<T>::epsilon();
+
+        /*on va chercher le vecteur correspondant à la plus petite valeur propre non-nulle de Ag*/
+        for(int i=1;i<=dimin;i++)
+        {
+            T temp = eigv.get(i,i);
+            idmin = ( temp <= vmin && temp >= eps*10e2 ? i : idmin);
+            vmin = ( temp <= vmin && temp >= eps*10e2 ? temp : vmin);
+        }
+    
+    if(eigval != NULL)
+        *eigval = vmin;
+        
+    return Cola( instance.getLeigvec(), idmin);
+}
+
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+/*--------------------------------------------------------------------------------*/
+
+/*homoproj.cpp templated*/
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> crossProductHomography( Mat<T> C1, Mat<T> C2)
+{
+    Mat<T> r1( (T)0, 1, 3);
+    Mat<T> r2(C1.get(3,1)*C2);
+
+    r1 = operatorL( operatorL(r1, -C1.get(3,1)*C2), C1.get(2,1)*C2);
+    r2 = operatorL( operatorL(r2, Mat<T>((T)0, 1,3) ), -C1.get(1,1)*C2);
+
+    return operatorC(r1,r2);
+}
+
+
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+Mat<T> MiseEnFormeProjection( Mat<T> C1, Mat<T> C2)
+{
+    int n = C2.getLine();
+    Mat<T> r1(((T)(-1))*transpose(C2));
+    //Mat<T> r1(transpose(C2));
+    Mat<T> r2((T)0, 1, n);
+
+    //r1 = operatorL( operatorL( r1, Mat<T>( (T)0, 1,n) ), ((T)(-1))*C1.get(1,1)*transpose(C2));
+    r1 = operatorL( operatorL( r1, Mat<T>( (T)0, 1,n) ), C1.get(1,1)*transpose(C2));    
+    //r2 = operatorL( operatorL( r2, transpose(C2) ), ((T)(-1))*C1.get(2,1)*transpose(C2) );
+    r2 = operatorL( operatorL( r2, ((T)(-1))*transpose(C2) ), C1.get(2,1)*transpose(C2) );
+
+    return operatorC(r1,r2);
+}
+
+
+
+
+/*----------------------------------------------*/
+
+
+template<typename T>
+Mat<T> MiseEnFormeRetroProjection(Mat<T> C1, Mat<T> C2)
+{
+    int n = C2.getLine();
+    Mat<T> r1(((T)(-1))*transpose(C2));
+    Mat<T> r2((T)0, 1, n);
+    Mat<T> r3(operatorL(r2,r2));
+
+    r1 = operatorL( operatorL( operatorL( r1, r2 ), r2), C1.get(1,1)*transpose(C2));
+    r2 = operatorL( operatorL( operatorL( r2, ((T)(-1))*transpose(C2) ), r2), C1.get(2,1)*transpose(C2) );
+    r3 = operatorL( r3, operatorL( ((T)(-1))*transpose(C2), C1.get(3,1)*transpose(C2)) );
+
+    return operatorC( operatorC(r1,r2), r3);
+}
+
+/*---------------------------------------------*/
+
+
+template<typename T>    /*pas de point virgule en fin de ligne...*/
+/*compute Homography/Projection between correspondances of X1 and X2 's columns 2D or 3D
+ * X1 : points in the image in homogeneous coordinates  that are stacked as columns of this matrix.
+ * X2 : corresponding points in the image, or in the 3D space, in homogeneous coordinate  that are stacked as columns of this matrix.
+ * method : SVD of a squared matrix (2) or non-squared matrix(1).
+ * Singular Value Decomposition of the system created by stacking the #(columns of X1) systems :
+ * the solution is the vector associated with the smallest non-zero singular value.
+ *
+ *
+ * The Homography matrix in homogeneous coordinates is returned : H.
+ */
+
+Mat<T> computeHomoProj(Mat<T> X1, Mat<T> X2, int method = 1)
+{
+    Mat<T> H( (T)0, 1,1);    
+    Mat<T> (*ptrFonction)(Mat<T>,Mat<T>);
+
+    if( X1.getColumn() == X2.getColumn() || X1.getColumn() == X2.getColumn()+1 || X1.getColumn()+1 == X2.getColumn())
+    /*gestion du cas d'homographie 2D ou d'une projection 2D->3D ou 3D->2D.*/
+    {
+        int nbrP = X1.getColumn();
+
+        /*en supposant que les points sont en coordonnées homogènes sur les colonnes de X1 et X2*/
+        homogeneousNormalization(&X1);
+        homogeneousNormalization(&X2);
+        //mettre les valeurs de la dernière coordonnée a 1.
+        cout << "X1 : " << endl;
+        X1.afficher();
+        cout << "/---------------------------------/" << endl;
+        cout << "X2 : " << endl;
+        X2.afficher();
+        cout << "/---------------------------------/" << endl;
+
+        /*choix du type de fonction a utiliser en fonction de ce que l'on fait.*/
+        if(X1.getLine() == X2.getLine())
+            ptrFonction = crossProductHomography;
+        else if( (X1.getLine()+1) == X2.getLine())
+            ptrFonction = MiseEnFormeProjection;
+        else
+            ptrFonction = MiseEnFormeRetroProjection;
+
+        Mat<T>* Ag = NULL;
+        Mat<T>** A = new Mat<T>*[nbrP];
+        for(int i=0;i<= nbrP-1;i++)
+        {
+
+            /*creation des matrices liée au produit en croix xi' X Hxi = 0 */
+            A[i] = new Mat<T>( (*ptrFonction)( Cola(X1, i+1), Cola(X2, i+1) ) );
+            /*attention : il est impératif que les points 3D si on calcul une projection se trouve dans la matrice X2.*/
+
+            /*column stacking*/
+            if(i==0)
+                Ag = new Mat<T>(*A[0]);
+            else
+                *Ag = operatorC( *Ag, *A[i]);
+        }
+
+        /*creation du systeme : done */
+        if(Ag->getLine() > Ag->getColumn())
+        {
+            //*Ag = transpose(*Ag);
+            //cout << "Ag possede plus de ligne que de colonne... On l\'a transposée." << endl;
+        }
+        cout << "Matrice Ag :" << endl;
+        Ag->afficher();        
+        /*------------------------------*/
+
+        int mode = 1;
+        switch(mode)
+        {
+            case 0 :
+        {
+            /*resolution de Ag*h = 0.0 : gaussj*/
+            Mat<T> solb((T)10e-15, Ag->getLine(), 1);
+            Mat<T> invtAA(transpose(*Ag)*(*Ag));
+            gaussj(&invtAA, &solb, 1);
+
+            /*reecriture*/
+            if(X1.getLine() == X2.getLine() )
+            {
+                H = operatorC( operatorC( transpose(extract(solb, 1,1, 3,1)), transpose(extract(solb, 4,1, 6,1))), transpose(extract(solb, 7,1, 9,1)));
+            }
+            else/* dans ce cas, h possede 12 lignes et H est une matrice 3x4.*/
+            {
+                if( X1.getLine()+1==X2.getLine())
+                    H = operatorC( operatorC( transpose(extract(solb, 1,1, 4,1)), transpose(extract(solb, 5,1, 8,1)) ), transpose(extract(solb, 9,1, 12,1)) );
+                else
+                    H = operatorC( operatorC( operatorC( transpose(extract(solb, 1,1, 3,1)), transpose(extract(solb, 4,1, 6,1)) ), transpose(extract(solb, 7,1, 9,1)) ), transpose(extract(solb, 10,1, 12,1)));
+            }
+
+        }
+            break;
+
+
+
+            case 1 :
+            /*resolution de Ag*h = 0 : svd de Ag*/
+            /*method 1: non-sqared matrix ; 2:squared matrix.*/
+            SVD<T> instance((method==1? *Ag : transpose(*Ag)*(*Ag)), 100);
+            Mat<T> U(instance.getU());
+            Mat<T> S(instance.getS());
+            Mat<T> V(instance.getV());
+            /*------*/
+            cout << "Matrice U :" << endl;
+            U.afficher();
+            cout << "Matrice S :" << endl;
+            S.afficher();
+            cout << "Matrice V :" << endl;
+            V.afficher();
+
+            /*------*/
+
+            int dimin = (S.getLine() <= S.getColumn() ? S.getLine() : S.getColumn() ); /*a bit useless in the second method though.*/
+            /* car rank(S) <= min(dimAColumn, dimALine). Inutile d'aller chercher plus loin sur la diagonale, on sait que les valeurs sont nulles. A moins que la matrice n'ai pas ses valeurs singulières d'ordonnées ?*/
+            int idmin = dimin;
+            T vmin = S.get(1,1);
+            T eps = numeric_limits<T>::epsilon();
+
+            /*on va chercher le vecteur correspondant à la plus petite valeur singulière non-nulle de Ag*/
+            for(int i=1;i<=dimin;i++)
+            {
+                T temp = S.get(i,i);
+                idmin = ( temp <= vmin /*&& temp >= eps*10e4*/ ? i : idmin);
+                vmin = ( temp <= vmin /*&& temp >= eps*10e4*/ ? temp : vmin);
+            }
+
+            /*solution*/            
+            Mat<T> h1( Cola(V, idmin));
+
+            /*reecriture*/
+            if(X1.getLine() == X2.getLine() )
+            {
+                H = operatorC( operatorC( transpose(extract(h1, 1,1, 3,1)), transpose(extract(h1, 4,1, 6,1))), transpose(extract(h1, 7,1, 9,1)));                
+            }            
+            else/* dans ce cas, h possede 12 lignes et H est une matrice 3x4.*/
+            {
+                if( X1.getLine()+1==X2.getLine())
+                {
+                    H = operatorC( operatorC( transpose(extract(h1, 1,1, 4,1)), transpose(extract(h1, 5,1, 8,1)) ), transpose(extract(h1, 9,1, 12,1)) );
+                }
+                else
+                {
+                    H = operatorC( operatorC( operatorC( transpose(extract(h1, 1,1, 3,1)), transpose(extract(h1, 4,1, 6,1)) ), transpose(extract(h1, 7,1, 9,1)) ), transpose(extract(h1, 10,1, 12,1)));
+                }
+            }
+
+            break;
+        }
+        cout << "Matrice Homography :" << endl;
+        cout << "H (issue de V) : " << endl;
+        H.afficher();
+
+#ifdef verbose
+        cout << "Test :" << endl;
+        for(int c=1;c<=X2.getColumn();c++)
+        {
+            (Cola(X2,c)).afficher();
+            Mat<double> temp(H*extract(X2, 1,c, X2.getLine(), c));
+            homogeneousNormalization(&temp);
+            temp.afficher();
+            (Cola(X1,c)).afficher();
+        }
+#endif
+        /*------------------------------*/
+        /*nettoyage*/
+        for(int i=0;i<=nbrP-1;i++)  delete A[i];
+        delete A;
+        delete Ag;
+
+    }
+    else
+    {
+        cerr << "ERREUR : les nombres de points correspondants ne correspondent pas, ni pour une homographie, ni pour une projection." << endl;
+    }
+
+
+    return H;
+}
+
+
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+/*------------------------------------------------------------*/
+
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LinkedList/LinkedList.cpp	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,195 @@
+/**
+ * @file    LinkedList.cpp
+ * @brief   Core Utility - Templated Linked List class
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LinkedList.h"    // api wrapper
+#include "LogUtil.h"
+
+template<class retT>
+LinkedList<retT>::LinkedList()
+{
+    // clear the member
+    _head = 0;
+
+    return;
+}
+
+template<class retT>
+LinkedList<retT>::~LinkedList()
+{
+    // free any memory that is on the heap
+    while(remove(1) != NULL);
+
+    return;
+}
+
+template<class retT>
+retT *LinkedList<retT>::push(void *data)
+{
+    retT *new_node = new retT [1];
+    // make sure the new object was allocated
+    if (0 == new_node)
+    {
+        ERROR("Memory allocation failed\n");
+    }
+    // update the next item in the list to the current head
+    new_node->next = _head;
+    // store the address to the linked datatype
+    new_node->data = data;
+    _head = new_node;
+
+    return _head;
+}
+
+//template<class retT>
+//retT *LinkedList<retT>::insert(void *data, uint32_t loc)
+//{
+//    retT *new_node = new retT [1];
+//    // make sure the new object was allocated
+//    if (0 == new_node)
+//    {
+//        ERROR("Memory allocation failed\n");
+//    }
+//    retT *current = _head->next;
+//    retT *prev = _head;
+//    // move to the item we want to insert
+//    for (uint32_t i=1; i!=(loc-1); i++)
+//    {
+//        prev = current;
+//        current = current->next;
+//    }
+//    // store the address to the linked datatype
+//    new_node->data = data;
+//    // clear the next pointer
+//    new_node->next = 0;
+//    // update the list and store the new stuff
+//    prev->next = new_node;
+//    new_node->next = current;
+//    // store the address to the linked datatype
+//    _head->data = data;
+//
+//    return prev->next;
+//}
+
+template<class retT>
+retT *LinkedList<retT>::append(void *data)
+{
+    retT *current = _head;
+    retT *new_node = new retT [1];
+    // make sure the new object was allocated
+    if (0 == new_node)
+    {
+        ERROR("Memory allocation failed\n");
+    }
+    // store the address to the linked datatype
+    new_node->data = data;
+    // clear the next pointer
+    new_node->next = 0;
+    // check for an empty list
+    if (0 == current)
+    {
+        _head = new_node;
+        return _head;
+    }
+    else
+    {
+        // look for the end of the list
+        while (current->next != 0)
+        {
+            current = current->next;
+        }
+        // and then add the new item to the list
+        current->next = new_node;
+    }
+
+    return current->next;
+}
+
+template<class retT>
+retT *LinkedList<retT>::remove(uint32_t loc)
+{
+    retT *current = _head;
+    retT *prev = 0;
+    // make sure we have an item to remove
+    if ((loc <= length()) && (loc > 0))
+    {
+        // move to the item we want to delete
+        if (1 == loc)
+        {
+            _head = current->next;
+            delete [] current;
+        }
+        else
+        {
+            for (uint32_t i=2; i<=loc; ++i)
+            {
+                prev = current;
+                current = current->next;
+            }
+            // store the item + 1 to replace what we are deleting
+            prev->next = current->next;
+            delete [] current;
+        }
+    }
+
+    return _head;
+}
+
+template<class retT>
+retT *LinkedList<retT>::pop(uint32_t loc)
+{
+    retT *current = _head;
+    // make sure we have something in the location
+    if ((loc > length()) || (loc == 0))
+    {
+        return 0;
+    }
+    // and if so jump down the list
+    for (uint32_t i=2; i<=loc; ++i)
+    {
+        current = current->next;
+    }
+
+    return current;
+}
+
+template<class retT>
+uint32_t LinkedList<retT>::length(void)
+{
+    int32_t count = 0;
+    retT *current = _head;
+    //loop until the end of the list is found
+    while (current != 0)
+    {
+        ++count;
+        current = current->next;
+    }
+
+    return count;
+}
+
+// pre-define the type for the linker
+template class LinkedList<node>;
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LinkedList/LinkedList.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,124 @@
+/**
+ * @file    LinkedList.h
+ * @brief   Core Utility - Templated Linked List class
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LINKEDLIST_H_
+#define LINKEDLIST_H_
+
+#include <mbed.h>
+#include <stdint.h>
+
+/**
+ *  @struct node
+ *  @brief The Linked List structure
+ */ 
+struct node
+{
+    void *data;         /*!< pointer to list member data */
+    struct node *next;  /*!< pointer to the next list member */
+};
+
+/** Example using the LinkedList Class
+ * @code
+ *  #include "mbed.h"
+ *  #include "LinkedList.h"
+ *  
+ *  LinkedList<node>list;
+ *  
+ *  int main()
+ *  {
+ *      node *tmp;
+ *      
+ *      list.push((char *)"Two\n");
+ *      list.append((char *)"Three\n");
+ *      list.append((char *)"Four\n");
+ *      list.push((char*)"One\n");
+ *      list.append((char*)"Five\n");
+ *      
+ *      for(int i=1; i<=list.length(); i++)
+ *      {
+ *          tmp = list.pop(i);
+ *          printf("%s", (char *)tmp->data);
+ *      }
+ *      
+ *      error("done\n");
+ *  }
+ * @endcode
+ */
+
+/**
+ *  @class LinkedList
+ *  @brief API abstraction for a Linked List
+ */ 
+template<class retT>
+class LinkedList
+{
+protected:
+    retT *_head;
+
+public:
+    /** Create the LinkedList object
+     */   
+    LinkedList();
+    
+    /** Deconstructor for the LinkedList object
+     *  Removes any members
+     */ 
+    ~LinkedList();
+
+    /** Add a member to the begining of the list
+     *  @param data - Some data type that is added to the list
+     *  @return The member that was just inserted (NULL if empty)
+     */
+    retT *push(void *data);
+    
+//    /** Add a member to some position in the list
+//     *  @param data - Some data type that is added to the list
+//     *  @param loc - Place in the list to put the data
+//     *  @return The member that was just inserted (NULL if empty)
+//     */
+//    retT *insert(void *data, uint32_t loc);
+    
+    /** Add a member to the end of the list
+     *  @param data - Some data type that is added to the list
+     *  @return The member that was just inserted (NULL if empty)
+     */
+    retT *append(void *data);
+    
+    /** Remove a member from the list
+     *  @param loc - The location of the member to remove
+     *  @return The head of the list
+     */
+    retT *remove(uint32_t loc);
+    
+    /** Get access to a member from the list
+     *  @param loc - The location of the member to access
+     *  @return The member that was just requested (NULL if empty or out of bounds)
+     */
+    retT *pop(uint32_t loc);
+    
+    /** Get the length of the list
+     *  @return The number of members in the list
+     */
+    uint32_t length(void);
+};
+
+#endif /* LINKEDLIST_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LogUtil/LogUtil.cpp	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,37 @@
+/**
+ * @file    LogUtil.cpp
+ * @brief   Utility to log messages during runtime
+ * @author  sam grove
+ * @version 1.0
+ * @see     http://www.drdobbs.com/cpp/a-lightweight-logger-for-c/240147505
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+ #include "LogUtil.h"
+ #include "mbed.h"
+ 
+LogUtil::LogUtil(Serial &serial, uint32_t baudrate)
+{
+    _serial = &serial;
+    (baudrate > 0) ? _serial->baud(baudrate) : __nop();
+    _serial->printf("\033[2J");  // clear the terminal
+    _serial->printf("\033[1;1H");// and set the cursor to home
+    wait(0.5f);
+    return;
+}
+     
+ 
+ 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LogUtil/LogUtil.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,91 @@
+/**
+ * @file    LogUtil.h
+ * @brief   Utility to log messages during runtime
+ * @author  sam grove
+ * @version 1.0
+ * @see     http://www.drdobbs.com/cpp/a-lightweight-logger-for-c/240147505
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#ifndef LOGUTIL_H
+#define LOGUTIL_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mbed.h"
+
+#define STREAM      stdout
+#define LOG(...)    \
+    fprintf(STREAM, "LOG:   %s L#%d ", __PRETTY_FUNCTION__, __LINE__);  \
+    fprintf(STREAM, ##__VA_ARGS__); \
+    fflush(STREAM)
+#define WARN(...)   \
+    fprintf(STREAM, "WARN:  %s L#%d ", __PRETTY_FUNCTION__, __LINE__);  \
+    fprintf(STREAM, ##__VA_ARGS__); \
+    fflush(STREAM)
+#define ERROR(...)  \
+    fprintf(STREAM, "ERROR: %s L#%d ", __PRETTY_FUNCTION__, __LINE__); \
+    fprintf(STREAM, ##__VA_ARGS__); \
+    fflush(STREAM); \
+    exit(1)
+ 
+/** Using the LogUtil class
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "LogUtil.h"
+ *  
+ *  LogUtil logger;
+ *
+ *  int main()
+ *  {
+ *     LOG("This is a log\n");
+ *     WARN("This is a warning\n");
+ *
+ *     for(int i=0; i<3; ++i) {
+ *         LOG("Log message #%d\n", i);
+ *     }
+ *
+ *     for(int i=0; i<3; ++i) {
+ *         WARN("Warn message #%d\n", i);
+ *     }
+ *
+ *     ERROR("This is an error\n");
+ *  }
+ * @endcode
+ */
+    
+/**
+ *  @class LogUtil
+ *  @brief Different ways to log messages having a standard interface
+ */ 
+class LogUtil
+{
+private:
+    Serial *_serial;
+public:
+    
+    /** Construct the LogUtil class and configure
+     */
+    LogUtil(Serial &serial, uint32_t baudrate = 0);
+        
+};
+    
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Map/Map.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,19 @@
+
+#ifndef MAP_H_
+#define MAP_H_
+
+#include "Obstacle.h"
+#include "LinkedList.h"
+
+
+class Map
+{
+    public:
+        Map();
+    
+    private:
+        LinkedList<Obstacle*> ll_obstacle;
+};
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Map/Obstacle/Obstacle.cpp	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,11 @@
+#include "Obstacle.h"
+
+Obstacle::Obstacle(float robotWidth)
+{
+    this->robotWidth = robotWidth;
+    bigShape = true;
+    
+    lastId++;
+    id = lastId;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Map/Obstacle/Obstacle.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,26 @@
+
+#ifndef OBSTABLE_H_
+#define OBSTABLE_H_
+
+class Obstacle
+{
+    public:
+        static int lastId;
+        
+        Obstacle(float robotWidth);
+        
+        virtual int height(float x, float y) = 0;
+        
+        void setBigShape(bool bs) {bigShape = bs;}
+        bool isBigShape() {return bigShape;}
+        
+        int getId() {return id;}
+        
+    private:
+        bool bigShape;
+        float robotWidth;
+        
+        int id;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Odometry/Odometry.cpp	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,79 @@
+/**
+ * @author BERTELONE Benjamin
+ *
+ * @section DESCRIPTION
+ * 
+ */
+
+#include "Odometry.h"
+
+Serial pc(USBTX, USBRX); // tx, rx
+
+
+Odometry::Odometry(QEI *qei_left, QEI *qei_right, float radius_left, float radius_right, float v)
+{
+    m_qei_left = qei_left;
+    m_qei_right = qei_right;
+    m_radiusPerTick_left = radius_left/qei_left->getPulsesPerRev();
+    m_radiusPerTick_right = radius_right/qei_right->getPulsesPerRev();
+    m_v = v;
+    
+    m_pulses_left = qei_left->getPulses();
+    m_pulses_right = qei_right->getPulses();
+    
+    setPos(0,0,0);
+    
+    updater.attach(this, &Odometry::update, 0.5);
+}
+
+void Odometry::setPos(float x, float y, float theta)
+{
+    this->x = x;
+    this->y = y;
+    this->theta = theta;
+}
+
+void Odometry::setX(float x)
+{
+    this->x = x;
+}
+
+void Odometry::setY(float Y)
+{
+    this->y = y;
+}
+
+void Odometry::setTheta(float theta)
+{
+    this->theta = theta;
+}
+
+void Odometry::reset()
+{
+    setPos(0,0,0);
+    m_pulses_left = m_qei_left->getPulses();
+    m_pulses_right = m_qei_right->getPulses();
+}
+
+void Odometry::update()
+{
+    DigitalOut myled(LED1);
+    myled = 1;
+    int delta_left = m_qei_left->getPulses() - m_pulses_left;
+    m_pulses_left = m_qei_left->getPulses();
+    int delta_right = m_qei_right->getPulses() - m_pulses_right;
+    m_pulses_right = m_qei_right->getPulses();
+    
+    float deltaS = (m_radiusPerTick_left*delta_left + m_radiusPerTick_right*delta_right) / 2.0;
+    float deltaTheta = (m_radiusPerTick_right*delta_right - m_radiusPerTick_left*delta_left) / m_v;
+    
+    x += deltaS*cos(theta);
+    y += deltaS*sin(theta);
+    theta += deltaTheta;
+    myled = 0;
+}
+
+
+
+   
+    
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Odometry/Odometry.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,38 @@
+#ifndef ODOMETRY_H
+#define ODOMETRY_H
+
+#include "mbed.h"
+#include "QEI.h"
+
+class Odometry
+{
+    public:
+        Odometry(QEI *qei_left, QEI *qei_right, float radius_left, float radius_right, float v);
+        
+        void setPos(float x, float y, float theta);
+        void setX(float x);
+        void setY(float Y);
+        void setTheta(float theta);
+        
+        float getX() {return x;}
+        float getY() {return y;}
+        float getTheta() {return theta;}
+        
+        void reset();
+    
+    private:
+        QEI* m_qei_left;
+        int m_pulses_left;
+        QEI* m_qei_right;
+        int m_pulses_right;
+        
+        float x, y, theta;
+        
+        float m_radiusPerTick_left, m_radiusPerTick_right, m_v;
+        
+        Ticker updater;
+        
+        void update();
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI/QEI.cpp	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,289 @@
+/**
+ * @author Aaron Berk
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * Quadrature Encoder Interface.
+ *
+ * A quadrature encoder consists of two code tracks on a disc which are 90
+ * degrees out of phase. It can be used to determine how far a wheel has
+ * rotated, relative to a known starting position.
+ *
+ * Only one code track changes at a time leading to a more robust system than
+ * a single track, because any jitter around any edge won't cause a state
+ * change as the other track will remain constant.
+ *
+ * Encoders can be a homebrew affair, consisting of infrared emitters/receivers
+ * and paper code tracks consisting of alternating black and white sections;
+ * alternatively, complete disk and PCB emitter/receiver encoder systems can
+ * be bought, but the interface, regardless of implementation is the same.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |  ^  |     |     |     |     |
+ *            ---+  ^  +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  +-----+     +-----+     +-----+
+ * Channel B     ^  |     |     |     |     |     |
+ *            ------+     +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  ^
+ *               90deg
+ *
+ * The interface uses X2 encoding by default which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * channel A.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^     ^     ^     ^     ^
+ *               ^     ^     ^     ^     ^
+ * Pulse count 0 1     2     3     4     5  ...
+ *
+ * This interface can also use X4 encoding which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * either channel.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ *
+ * It defaults
+ *
+ * An optional index channel can be used which determines when a full
+ * revolution has occured.
+ *
+ * If a 4 pules per revolution encoder was used, with X4 encoding,
+ * the following would be observed.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  +--+  ^  ^  +--+  ^
+ *               ^  ^  ^  |  |  ^  ^  |  |  ^
+ * Index      ------------+  +--------+  +-----------
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ * Rev.  count 0          1           2
+ *
+ * Rotational position in degrees can be calculated by:
+ *
+ * (pulse count / X * N) * 360
+ *
+ * Where X is the encoding type [e.g. X4 encoding => X=4], and N is the number
+ * of pulses per revolution.
+ *
+ * Linear position can be calculated by:
+ *
+ * (pulse count / X * N) * (1 / PPI)
+ *
+ * Where X is encoding type [e.g. X4 encoding => X=44], N is the number of
+ * pulses per revolution, and PPI is pulses per inch, or the equivalent for
+ * any other unit of displacement. PPI can be calculated by taking the
+ * circumference of the wheel or encoder disk and dividing it by the number
+ * of pulses per revolution.
+ */
+
+/**
+ * Includes
+ */
+#include "QEI.h"
+
+QEI::QEI(PinName channelA,
+         PinName channelB,
+         PinName index,
+         int pulsesPerRev,
+         Encoding encoding) : channelA_(channelA), channelB_(channelB),
+        index_(index) {
+
+    pulses_       = 0;
+    revolutions_  = 0;
+    pulsesPerRev_ = pulsesPerRev;
+    encoding_     = encoding;
+
+    //Workout what the current state is.
+    int chanA = channelA_.read();
+    int chanB = channelB_.read();
+
+    //2-bit state.
+    currState_ = (chanA << 1) | (chanB);
+    prevState_ = currState_;
+
+    //X2 encoding uses interrupts on only channel A.
+    //X4 encoding uses interrupts on      channel A,
+    //and on channel B.
+    channelA_.rise(this, &QEI::encode);
+    channelA_.fall(this, &QEI::encode);
+
+    //If we're using X4 encoding, then attach interrupts to channel B too.
+    if (encoding == X4_ENCODING) {
+        channelB_.rise(this, &QEI::encode);
+        channelB_.fall(this, &QEI::encode);
+    }
+    //Index is optional.
+    if (index !=  NC) {
+        index_.rise(this, &QEI::index);
+    }
+
+}
+
+void QEI::reset(void) {
+
+    pulses_      = 0;
+    revolutions_ = 0;
+
+}
+
+int QEI::getCurrentState(void) {
+
+    return currState_;
+
+}
+
+int QEI::getPulses(void) {
+
+    return pulses_;
+
+}
+
+int QEI::getRevolutions(void) {
+
+    return revolutions_;
+
+}
+
+// +-------------+
+// | X2 Encoding |
+// +-------------+
+//
+// When observing states two patterns will appear:
+//
+// Counter clockwise rotation:
+//
+// 10 -> 01 -> 10 -> 01 -> ...
+//
+// Clockwise rotation:
+//
+// 11 -> 00 -> 11 -> 00 -> ...
+//
+// We consider counter clockwise rotation to be "forward" and
+// counter clockwise to be "backward". Therefore pulse count will increase
+// during counter clockwise rotation and decrease during clockwise rotation.
+//
+// +-------------+
+// | X4 Encoding |
+// +-------------+
+//
+// There are four possible states for a quadrature encoder which correspond to
+// 2-bit gray code.
+//
+// A state change is only valid if of only one bit has changed.
+// A state change is invalid if both bits have changed.
+//
+// Clockwise Rotation ->
+//
+//    00 01 11 10 00
+//
+// <- Counter Clockwise Rotation
+//
+// If we observe any valid state changes going from left to right, we have
+// moved one pulse clockwise [we will consider this "backward" or "negative"].
+//
+// If we observe any valid state changes going from right to left we have
+// moved one pulse counter clockwise [we will consider this "forward" or
+// "positive"].
+//
+// We might enter an invalid state for a number of reasons which are hard to
+// predict - if this is the case, it is generally safe to ignore it, update
+// the state and carry on, with the error correcting itself shortly after.
+void QEI::encode(void) {
+
+    int change = 0;
+    int chanA  = channelA_.read();
+    int chanB  = channelB_.read();
+
+    //2-bit state.
+    currState_ = (chanA << 1) | (chanB);
+
+    if (encoding_ == X2_ENCODING) {
+
+        //11->00->11->00 is counter clockwise rotation or "forward".
+        if ((prevState_ == 0x3 && currState_ == 0x0) ||
+                (prevState_ == 0x0 && currState_ == 0x3)) {
+
+            pulses_++;
+
+        }
+        //10->01->10->01 is clockwise rotation or "backward".
+        else if ((prevState_ == 0x2 && currState_ == 0x1) ||
+                 (prevState_ == 0x1 && currState_ == 0x2)) {
+
+            pulses_--;
+
+        }
+
+    } else if (encoding_ == X4_ENCODING) {
+
+        //Entered a new valid state.
+        if (((currState_ ^ prevState_) != INVALID) && (currState_ != prevState_)) {
+            //2 bit state. Right hand bit of prev XOR left hand bit of current
+            //gives 0 if clockwise rotation and 1 if counter clockwise rotation.
+            change = (prevState_ & PREV_MASK) ^ ((currState_ & CURR_MASK) >> 1);
+
+            if (change == 0) {
+                change = -1;
+            }
+
+            pulses_ -= change;
+        }
+
+    }
+
+    prevState_ = currState_;
+
+}
+
+void QEI::index(void) {
+
+    revolutions_++;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI/QEI.h	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,246 @@
+/**
+ * @author Aaron Berk
+ *
+ * @section LICENSE
+ *
+ * Copyright (c) 2010 ARM Limited
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @section DESCRIPTION
+ *
+ * Quadrature Encoder Interface.
+ *
+ * A quadrature encoder consists of two code tracks on a disc which are 90
+ * degrees out of phase. It can be used to determine how far a wheel has
+ * rotated, relative to a known starting position.
+ *
+ * Only one code track changes at a time leading to a more robust system than
+ * a single track, because any jitter around any edge won't cause a state
+ * change as the other track will remain constant.
+ *
+ * Encoders can be a homebrew affair, consisting of infrared emitters/receivers
+ * and paper code tracks consisting of alternating black and white sections;
+ * alternatively, complete disk and PCB emitter/receiver encoder systems can
+ * be bought, but the interface, regardless of implementation is the same.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |  ^  |     |     |     |     |
+ *            ---+  ^  +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  +-----+     +-----+     +-----+
+ * Channel B     ^  |     |     |     |     |     |
+ *            ------+     +-----+     +-----+     +-----
+ *               ^  ^
+ *               ^  ^
+ *               90deg
+ *
+ * The interface uses X2 encoding by default which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * channel A.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^     ^     ^     ^     ^
+ *               ^     ^     ^     ^     ^
+ * Pulse count 0 1     2     3     4     5  ...
+ *
+ * This interface can also use X4 encoding which calculates the pulse count
+ * based on reading the current state after each rising and falling edge of
+ * either channel.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ *
+ * It defaults
+ *
+ * An optional index channel can be used which determines when a full
+ * revolution has occured.
+ *
+ * If a 4 pules per revolution encoder was used, with X4 encoding,
+ * the following would be observed.
+ *
+ *               +-----+     +-----+     +-----+
+ * Channel A     |     |     |     |     |     |
+ *            ---+     +-----+     +-----+     +-----
+ *               ^     ^     ^     ^     ^
+ *               ^  +-----+  ^  +-----+  ^  +-----+
+ * Channel B     ^  |  ^  |  ^  |  ^  |  ^  |     |
+ *            ------+  ^  +-----+  ^  +-----+     +--
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ *               ^  ^  ^  +--+  ^  ^  +--+  ^
+ *               ^  ^  ^  |  |  ^  ^  |  |  ^
+ * Index      ------------+  +--------+  +-----------
+ *               ^  ^  ^  ^  ^  ^  ^  ^  ^  ^
+ * Pulse count 0 1  2  3  4  5  6  7  8  9  ...
+ * Rev.  count 0          1           2
+ *
+ * Rotational position in degrees can be calculated by:
+ *
+ * (pulse count / X * N) * 360
+ *
+ * Where X is the encoding type [e.g. X4 encoding => X=4], and N is the number
+ * of pulses per revolution.
+ *
+ * Linear position can be calculated by:
+ *
+ * (pulse count / X * N) * (1 / PPI)
+ *
+ * Where X is encoding type [e.g. X4 encoding => X=44], N is the number of
+ * pulses per revolution, and PPI is pulses per inch, or the equivalent for
+ * any other unit of displacement. PPI can be calculated by taking the
+ * circumference of the wheel or encoder disk and dividing it by the number
+ * of pulses per revolution.
+ */
+
+#ifndef QEI_H
+#define QEI_H
+
+/**
+ * Includes
+ */
+#include "mbed.h"
+
+/**
+ * Defines
+ */
+#define PREV_MASK 0x1 //Mask for the previous state in determining direction
+//of rotation.
+#define CURR_MASK 0x2 //Mask for the current state in determining direction
+//of rotation.
+#define INVALID   0x3 //XORing two states where both bits have changed.
+
+/**
+ * Quadrature Encoder Interface.
+ */
+class QEI {
+
+public:
+
+    typedef enum Encoding {
+
+        X2_ENCODING,
+        X4_ENCODING
+
+    } Encoding;
+
+    /**
+     * Constructor.
+     *
+     * Reads the current values on channel A and channel B to determine the
+     * initial state.
+     *
+     * Attaches the encode function to the rise/fall interrupt edges of
+     * channels A and B to perform X4 encoding.
+     *
+     * Attaches the index function to the rise interrupt edge of channel index
+     * (if it is used) to count revolutions.
+     *
+     * @param channelA mbed pin for channel A input.
+     * @param channelB mbed pin for channel B input.
+     * @param index    mbed pin for optional index channel input,
+     *                 (pass NC if not needed).
+     * @param pulsesPerRev Number of pulses in one revolution.
+     * @param encoding The encoding to use. Uses X2 encoding by default. X2
+     *                 encoding uses interrupts on the rising and falling edges
+     *                 of only channel A where as X4 uses them on both
+     *                 channels.
+     */
+    QEI(PinName channelA, PinName channelB, PinName index, int pulsesPerRev, Encoding encoding = X2_ENCODING);
+
+    /**
+     * Reset the encoder.
+     *
+     * Sets the pulses and revolutions count to zero.
+     */
+    void reset(void);
+
+    /**
+     * Read the state of the encoder.
+     *
+     * @return The current state of the encoder as a 2-bit number, where:
+     *         bit 1 = The reading from channel B
+     *         bit 2 = The reading from channel A
+     */
+    int getCurrentState(void);
+
+    /**
+     * Read the number of pulses recorded by the encoder.
+     *
+     * @return Number of pulses which have occured.
+     */
+    int getPulses(void);
+
+    /**
+     * Read the number of revolutions recorded by the encoder on the index channel.
+     *
+     * @return Number of revolutions which have occured on the index channel.
+     */
+    int getRevolutions(void);
+
+
+
+    /**
+     * Update the pulse count.
+     *
+     * Called on every rising/falling edge of channels A/B.
+     *
+     * Reads the state of the channels and determines whether a pulse forward
+     * or backward has occured, updating the count appropriately.
+     */
+    void encode(void);
+    
+    int getPulsesPerRev() {return pulsesPerRev_;}
+private:
+    /**
+     * Called on every rising edge of channel index to update revolution
+     * count by one.
+     */
+    void index(void);
+
+    Encoding encoding_;
+
+    InterruptIn channelA_;
+    InterruptIn channelB_;
+    InterruptIn index_;
+
+    int          pulsesPerRev_;
+    int          prevState_;
+    int          currState_;
+
+    volatile int pulses_;
+    volatile int revolutions_;
+
+};
+
+#endif /* QEI_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,294 @@
+#include "mbed.h"
+#include "QEI.h"
+#include "Odometry.h"
+#include <iostream>
+#include "Map.h"
+
+
+/*---------------------------------------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------------------------------------*/
+/*KalmanFilter*/
+
+#include "EKF.h"
+Mat<double> motion_bicycle3( Mat<double> state, Mat<double> command, double dt = 0.5);
+Mat<double> sensor_bicycle3( Mat<double> state, Mat<double> command, Mat<double> d_state, double dt = 0.5 );
+Mat<double> jmotion_bicycle3( Mat<double> state, Mat<double> command, double dt = 0.5);
+Mat<double> jsensor_bicycle3( Mat<double> state, Mat<double> command, Mat<double> d_state, double dt = 0.5);
+void measurementCallback( Mat<double>* z, Odometry* odometry);
+bool setPWM(PwmOut *servo,float p);
+
+Mat<double> bicycle(3,1);
+int reduc = 16;
+/*---------------------------------------------------------------------------------------------------------*/
+/*---------------------------------------------------------------------------------------------------------*/
+
+/*----------------------------------------------------------------------------------------------*/
+    /*Serial*/    
+    Serial pcs(USBTX, USBRX); // tx, rx
+/*----------------------------------------------------------------------------------------------*/
+
+/* --- Initialisation de la liste des obstable --- */
+int Obstacle::lastId = 0;
+
+
+int main()
+{
+
+    
+    PwmOut pw1(p22);
+    DigitalOut dir1(p21);
+    PwmOut pw2(p24);
+    DigitalOut dir2(p23);
+    
+    //mbuino
+    /*
+    PwmOut pw1(P0_17);
+    DigitalOut dir1(P0_18);
+    PwmOut pw2(P0_23);
+    DigitalOut dir2(P0_19);
+    */
+    /*
+    //nucleo
+    PwmOut pw1(PB_8);
+    DigitalOut dir1(D12);
+    PwmOut pw2(PB_9);
+    DigitalOut dir2(D13);
+    */
+    pw1.period_us(10);
+    pw2.period_us(10);
+    
+    
+    dir1.write(0);
+    dir2.write(0);    
+    pw1.write(1.0);
+    pw2.write(0.8);
+    //setPWM(&pw1,0.9);
+    pcs.printf("mise à jour des pwm.\n");
+    //while(1);
+    /*----------------------------------------------------------------------------------------------*/
+    /*Odometry*/
+    QEI qei_left(p15,p16,NC,1024*reduc,QEI::X4_ENCODING);
+    //QEI qei_left(P0_2,P0_7,NC,1024*reduc,QEI::X4_ENCODING);//mbuino
+    //QEI qei_left(PA_3,PA_2,NC,1024*reduc,QEI::X4_ENCODING);//nucleo
+    
+    QEI qei_right(p17,p18,NC,1024*reduc,QEI::X4_ENCODING);
+    //QEI qei_right(P0_8,P0_20,NC,1024*reduc,QEI::X4_ENCODING);//mbuino
+    //QEI qei_right(PA_10,PB_3,NC,1024*reduc,QEI::X4_ENCODING);//nucleo
+    
+    Odometry odometry(&qei_left,&qei_right,0.07,0.07,0.26);
+    /*----------------------------------------------------------------------------------------------*/
+    
+    
+    
+    /*----------------------------------------------------------------------------------------------*/
+    /*KalmanFilter*/
+    double phi_max = 100;
+    /*en millimetres*/
+    bicycle.set((double)100, 1,1);  /*radius*/
+    bicycle.set((double)100, 2,1);
+    bicycle.set((double)66, 3,1);   /*entre-roue*/
+    
+    int nbrstate = 5;
+    int nbrcontrol = 2;
+    int nbrobs = 5;
+    double dt = (double)0.05;
+    double stdnoise = (double)0.05;
+
+    Mat<double> initX((double)0, nbrstate, 1);  
+    initX.set( (double)0, 3,1);
+    
+    bool extended = true;
+    bool filterOn = false;
+    EKF<double> instance(&pcs, nbrstate, nbrcontrol, nbrobs, dt, stdnoise, /*current state*/ initX, extended, filterOn);
+    
+    instance.initMotion(motion_bicycle3);
+    instance.initSensor(sensor_bicycle3);
+    instance.initJMotion(jmotion_bicycle3);
+    instance.initJSensor(jsensor_bicycle3);
+    
+    /*desired State : (x y theta phiright phileft)*/
+    Mat<double> dX((double)0, nbrstate, 1);
+    dX.set( (double)100, 1,1);
+    dX.set( (double)0, 2,1);
+    dX.set( (double)0, 3,1);
+    dX.set( (double)0, 4,1);
+    dX.set( (double)0, 5,1);    
+    
+    Mat<double> ki((double)0, nbrcontrol, nbrstate);        
+    Mat<double> kp((double)0, nbrcontrol, nbrstate);
+    Mat<double> kd((double)0, nbrcontrol, nbrstate);
+    //Mat<double> kdd((double)0.0015, nbrcontrol, nbrstate);
+    
+    for(int i=1;i<=nbrstate;i++)
+    {
+        kp.set( (double)0.01, i, i);
+        kd.set( (double)0.0001, i, i);
+        ki.set( (double)0.0001, i, i);
+    }   
+    
+    instance.setKi(ki);
+    instance.setKp(kp);
+    instance.setKd(kd);
+    //instance.setKdd(kdd);
+    
+    Mat<double> u(transpose( instance.getCommand()) );
+    
+    /*Observations*/
+    /*il nous faut 5 observation :*/
+    Mat<double> z((double)0,5,1);
+    measurementCallback(&z, &odometry);    
+    
+    /*----------------------------------------------------------------------------------------------*/
+    
+    
+    while(1)
+    {
+        //wait(1);
+        pcs.printf("%f : %f : %f\n",odometry.getX()*100,odometry.getY()*100,odometry.getTheta()*180/3.14);                
+                
+        
+        /*------------------------------------------------------------------------------------------*/
+        /*Asservissement*/        
+        
+        //measurementCallback(&z, &odometry);                        
+        instance.measurement_Callback( instance.getX(), dX, true );
+         
+        instance.state_Callback();
+                
+        double phi_r = instance.getCommand().get(1,1);
+        double phi_l = instance.getCommand().get(2,1);
+        
+        double phi_max = 100;                    
+        
+        instance.computeCommand(dX, (double)dt, -2);        
+        pcs.printf("command : \n phi_r = %f \n phi_l = %f \n", phi_r/phi_max*100, phi_l/phi_max*100);
+        //instance.getX().afficher();
+        
+        
+        if(phi_r <= 0)
+            dir1.write(0);
+        else
+            dir1.write(1);
+            
+        if(phi_l <= 0)
+            dir2.write(0);
+        else
+            dir2.write(1);
+            
+        if(abs(phi_r/phi_max) < 1.0)
+            setPWM(&pw1, (float)abs(phi_r/phi_max));
+        else
+            cout << "P1..." << endl;
+            
+        if(abs(phi_l/phi_max) < 1.0)
+            setPWM(&pw2,(float)abs(phi_l/phi_max));
+        else
+            pcs.printf("P2...");
+            
+        pcs.printf("\n\n----------------- Commande mise executee. ------------------ \n\n");
+        
+    }
+}
+
+void measurementCallback( Mat<double>* z, Odometry* odometry)
+{
+    z->set( (double)/*conversionUnitée mm */odometry->getX(), 1,1);
+    z->set( (double)/*conversionUnitée mm*/odometry->getY(), 2,1);
+    z->set( (double)/*conversionUnitée rad*/odometry->getTheta(), 3,1);    
+}
+
+Mat<double> motion_bicycle3( Mat<double> state, Mat<double> command, double dt)
+{
+    Mat<double> r(state);
+    double v = bicycle.get(1,1)/(2*bicycle.get(3,1))*(r.get(4,1)+r.get(5,1));
+    double w = bicycle.get(1,1)/(2*bicycle.get(3,1))*(r.get(4,1)-r.get(5,1));
+    
+    r.set( r.get(1,1) + v*cos(r.get(3,1))*dt, 1,1);
+    r.set( r.get(2,1) + v*sin(r.get(3,1))*dt, 2,1);
+    
+    double angle = (r.get(3,1) + dt*w);
+    if( angle < -PI)
+    {
+        angle = angle - PI*ceil(angle/PI);
+    }
+    else if( angle > PI)
+    {
+        angle = angle - PI*floor(angle/PI);
+    }
+    
+    r.set( atan21(sin(angle), cos(angle)), 3,1);
+    
+        
+    /*----------------------------------------*/
+    /*Modele du moteur*/
+    /*----------------------------------------*/
+    double r1 = bicycle.get(3,1)/bicycle.get(1,1)*(command.get(1,1)/bicycle.get(3,1)+command.get(2,1));
+    double r2 = bicycle.get(3,1)/bicycle.get(1,1)*(command.get(1,1)/bicycle.get(3,1)-command.get(2,1));
+    
+    
+    r.set( r1, 4,1);
+    r.set( r2, 5,1);    
+    
+    
+    /*----------------------------------------*/
+    /*----------------------------------------*/    
+    
+    return r;
+}
+
+
+Mat<double> sensor_bicycle3( Mat<double> state, Mat<double> command, Mat<double> d_state, double dt)
+{    
+    return state;
+}
+
+
+Mat<double> jmotion_bicycle3( Mat<double> state, Mat<double> command, double dt)
+{
+    double h = numeric_limits<double>::epsilon()*10e2;
+    Mat<double> var( (double)0, state.getLine(), state.getColumn());
+    var.set( h, 1,1);
+    Mat<double> G(motion_bicycle3(state, command, dt) - motion_bicycle3(state+var, command,dt));
+    
+    for(int i=2;i<=state.getLine();i++)
+    {
+        var.set( (double)0, i-1,1);
+        var.set( h, i,1);
+        G = operatorL(G, motion_bicycle3(state, command, dt) - motion_bicycle3(state+var, command,dt) );
+    }       
+    
+    
+    return (1.0/h)*G;
+}
+
+Mat<double> jsensor_bicycle3( Mat<double> state, Mat<double> command, Mat<double> d_state, double dt)
+{
+    double h = numeric_limits<double>::epsilon()*10e2;
+    Mat<double> var((double)0, state.getLine(), state.getColumn());
+    var.set( h, 1,1);
+    Mat<double> H(sensor_bicycle3(state, command, d_state, dt) - sensor_bicycle3(state+var, command, d_state, dt));     
+    
+    for(int i=2;i<=state.getLine();i++)
+    {        
+        var.set( (double)0, i-1,1);
+        var.set( h, i,1);
+        Mat<double> temp(sensor_bicycle3(state, command, d_state, dt) - sensor_bicycle3(state+var, command, d_state, dt));
+        
+        H = operatorL(H, temp );        
+        pcs.printf("sensor bicycle  %d...\n",i);
+    }       
+    
+    
+    return (1.0/h)*H;
+}
+
+bool setPWM(PwmOut *servo,float p)
+{
+    if(p <= 1.0f && p >= 0.0f)
+    {
+        servo->write(p);        
+        return true;
+    }
+    
+    return false;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Dec 14 17:49:01 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5
\ No newline at end of file