root/applications/doprava/QuadraticMinimalizator.h @ 1420

Revision 1420, 5.3 kB (checked in by jabu, 12 years ago)

Minimalizator

Line 
1
2#ifndef QUADRATICMINIMALIZATOR_H
3#define QUADRATICMINIMALIZATOR_H
4
5#include <cstdlib>
6#include <itpp/itbase.h>
7#include <iostream>
8
9
10using namespace itpp;
11using namespace std;
12
13class QuadraticMinimalizator {
14protected:
15    mat A;
16    mat B;
17    mat Q;
18    mat R;
19    double maxdif;
20
21    bool test() {
22        if ( !isDiagonal(Q) ) {
23            stringstream e;
24            e << "Matrix Q is not diagonal" << endl;
25            e << Q << endl;
26            it_warning(e.str());
27        }
28        if ( !isDiagonal(R) ) {
29            stringstream e;
30            e << "Matrix R is not diagonal" << endl;
31            e << R << endl;
32            it_warning(e.str());
33        }
34        if ( !isPositiveDefinite(Q) ) {
35            stringstream e;
36            e << "Matrix Q is not positive definite" << endl;
37            e << Q << endl;
38            it_warning(e.str());
39        }
40        if ( !isPositiveDefinite(R) ) {
41            stringstream e;
42            e << "Matrix R is not positive definite" << endl;
43            e << R << endl;
44            it_warning(e.str());
45        }
46    }
47
48public:
49    QuadraticMinimalizator( const mat &A, const mat &B, const mat &Q, const mat &R ) {
50        maxdif = 0.00000001;
51        this->A = A;
52        this->B = B;
53        this->Q = Q;
54        this->R = R;
55        test();
56    }
57
58
59    /**
60     * x(t+1) = Ax(t) + Bu(t) + C
61     * @param horizont
62     * @param C
63     * @return L: u(t) = L [ x(t) 1 ]
64     */
65    mat L( const int horizont, const mat & C ) {
66        it_warning("Nijak se tam C neprojevuje!!!");
67        int xdim = A.cols();
68        int udim = B.cols();
69        mat sqQ = sqrt(Q);
70        mat sqR = sqrt(R);
71        mat M0, M;
72        mat qrQ;
73        mat Lall, Lc1, Lc2, Lc3, Lx1, Lx2, Lu, L;
74        M0 = concat_vertical(
75                concat_vertical(
76                    concat_horizontal( sqQ * B,   concat_horizontal( sqQ * A,             zeros(xdim, udim) ) ),
77                    concat_horizontal( sqR,       concat_horizontal( zeros( udim, xdim ), zeros(udim, udim) ) )
78                ),
79                concat_horizontal( zeros( xdim, xdim + udim ) , sqQ * C)
80            );
81
82        M = M0;
83        for (int h = horizont; h >= 0; h --) {
84            qr(M, Lall);
85
86            Lu  = Lall(0, udim-1, 0,         udim-1     );
87            Lx1 = Lall(0, udim-1, udim,      udim+xdim-1);
88            Lc1 = Lall(0, udim-1, udim+xdim, udim+xdim  );
89            Lx2 = Lall(udim, udim+xdim-1,  udim, udim+xdim-1);
90            Lc2 = Lall(udim, udim+xdim-1,  udim+xdim, udim+xdim);
91            Lc3 = Lall(udim+xdim, udim+xdim+xdim-1,  udim+xdim, udim+xdim);
92            M = concat_vertical(
93                    M0,
94                    concat_vertical(
95                        concat_horizontal( Lx2 * B, concat_horizontal( Lx2 * A, Lc2 ) ),
96                        concat_horizontal( zeros(xdim, xdim + udim), Lc3 )
97                    )
98                );
99        }
100        L = concat_horizontal( - inv(Lu) * Lx1, - inv(Lu) * Lc1);
101        return L;
102    }
103    /**
104     * x(t+1) = Ax(t) + Bu(t)
105     * @param horizont
106     * @param C
107     * @return L: u(t) = Lx(t)
108     */
109    mat L( const int horizont ) {
110        int xdim = A.cols();
111        int udim = B.cols();
112        mat sqQ = sqrt(Q);
113        mat sqR = sqrt(R);
114        mat M0, M;
115        mat qrQ;
116        mat Lall, Ls, Lx, Lu, L;
117        M0 = concat_vertical(
118                concat_horizontal( sqQ * B,     sqQ * A ),
119                concat_horizontal( sqR,         zeros( udim, xdim ) )
120            );
121        M = M0;
122        for (int h = horizont; h >= 0; h --) {
123            qr(M, Lall);
124            Lu = Lall(0,    udim-1,       0,    udim-1);
125            Lx = Lall(udim, udim+xdim-1,  udim, udim+xdim-1);
126            Ls = Lall(0,    udim-1,       udim, udim+xdim-1);
127            M = concat_vertical(
128                    M0,
129                    concat_horizontal(Lx * B, Lx * A )
130                );
131        }
132        L = - inv(Lu) * Ls;
133        return L;
134    }
135
136    double maxDif( const mat & M1, const mat & M2 ) {
137        return max(max(abs(M1 - M2), 1));
138    }
139
140    bool isSymmetric( const mat & M) {
141        return isSymmetric(M, maxdif);
142    }
143
144    bool isSymmetric( const mat & M, double maxdif ) {
145        mat D = abs(M - M.transpose());
146        double m = max(max(D, 1));
147        if ( m < maxdif )
148            return true;
149        else
150            return false;
151    }
152
153    bool isDiagonal(  const mat M ) {
154        mat D = abs(M);
155        for ( int i = 0; i < M.rows(); i ++ ) {
156            for ( int j = 0; j < M.cols(); j ++ ) {
157                if ( i != j && D(i,j) > maxdif ) {
158                    return false;
159                }
160            }
161        }
162        return true;
163    }
164
165    bool isPositiveDefinite( const mat M ) {
166        int dim = M.rows();
167        if ( dim != M.cols() ) {
168            stringstream err;
169            err << "Matrix " << M << " is not square";
170            it_warning(err.str());
171        } else {
172            for ( int i = dim-1; i >= 0; i-- ) {
173                // subdeterminanty
174                if ( det(M(0,i,0,i)) <= 0 ) {
175                    return false;
176                }
177            }
178            return true;
179        }
180        return false;
181    }
182
183
184
185
186};
187
188#endif  /* QUADRATICMINIMALIZATOR_H */
Note: See TracBrowser for help on using the browser.