00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "uvsim/utilities/utilities.h"
00020
00021 using namespace boost::numeric::ublas;
00022 using namespace boost::numeric::bindings;
00023
00024 namespace uvsim
00025 {
00026
00027
00028 bool fileExists(const char * filename)
00029 {
00030 if (FILE * file = fopen(filename, "r"))
00031 {
00032 fclose(file);
00033 return true;
00034 }
00035 return false;
00036 }
00037 std::string doubleToString(double val)
00038 {
00039 std::ostringstream out;
00040 out << val;
00041 return out.str();
00042 }
00043 std::string intToString(int val)
00044 {
00045 std::ostringstream out;
00046 out << std::setfill('0') << std::setw(3) << val;
00047 return out.str();
00048 }
00049
00050 static char *console_clearscreen = 0;
00051 static char *console_cursorposition = 0;
00052
00053 static bool console_initialize_terminfo()
00054 {
00055 int result;
00056 if (cur_term) return true;
00057 setupterm( NULL, STDOUT_FILENO, &result );
00058 if (result > 0)
00059 {
00060 console_clearscreen = tigetstr( "clear" );
00061 console_cursorposition = tigetstr( "cup" );
00062 }
00063 return (result > 0);
00064 }
00065
00066 void cursorxy( int col, int line )
00067 {
00068 if (console_initialize_terminfo())
00069 putp( tparm( console_cursorposition, line, col, 0, 0, 0, 0, 0, 0, 0 ) );
00070 }
00071
00072 void clear( bool gohome )
00073 {
00074 if (console_initialize_terminfo())
00075 {
00076 putp( console_clearscreen );
00077 if (gohome) cursorxy( 0, 0 );
00078 }
00079 }
00080
00081 void lowPass(const double &freq, const vector<double> &freqCut,
00082 const vector<double> &x, vector<double> &y)
00083 {
00084 double alpha, dt;
00085 dt = 1/freq;
00086 for (int i=0; i<y.size(); i++)
00087 {
00088 alpha = dt / (1/ (freqCut(i)*M_PI) + dt);
00089 y(i) = alpha*x(i) + (1-alpha)*y(i);
00090 }
00091 }
00092
00093 matrix<double> ones(int m, int n)
00094 {
00095 matrix<double> A(m,n);
00096 for (int i=0;i<m;i++)
00097 for (int j=0;j<n;j++)
00098 A(i,j) = 1;
00099 return A;
00100 }
00101
00102 matrix<double> skew(vector<double> &v)
00103 {
00104 matrix<double> m(3,3);
00105 m(0,0) = 0;
00106 m(1,0) = -v(2);
00107 m(2,0) = v(1);
00108 m(0,1) = v(2);
00109 m(1,1) = 0;
00110 m(2,1) = -v(0);
00111 m(0,2) = -v(1);
00112 m(1,2) = v(0);
00113 m(2,2) = 0;
00114 return m;
00115 }
00116
00117 double max(vector<double> v)
00118 {
00119 double max = v(0);
00120 for (int i=1;i<v.size();i++)
00121 {
00122 if (v(i) > max) max = v(i);
00123 }
00124 return max;
00125 }
00126
00131 matrix<double> inv(const matrix<double>& input)
00132 {
00133 typedef permutation_matrix<std::size_t> pmatrix;
00134
00135 int n = input.size1();
00136 if (input.size2() != n) std::cout << "Error: matrix must be square." << std::endl;
00137 matrix<double> A(input), inverse(n,n);
00138
00139 pmatrix pm(A.size1());
00140
00141
00142 int res = lu_factorize(A,pm);
00143 if ( res != 0 ) std::cout << "Error in inverse" << std::endl;
00144
00145
00146 inverse.assign(identity_matrix<double>(n));
00147
00148
00149 lu_substitute(A, pm, inverse);
00150 return inverse;
00151 }
00152
00153 matrix<double> pinv(matrix<double> A)
00154 {
00155 matrix<double, column_major> Ac = A;
00156 int m = A.size1(), n = A.size2();
00157 int maxDim = std::max(m,n), minDim = std::min(m,n);
00158 vector<double> Sig(minDim);
00159 matrix<double, column_major> U(m,m), SigI(n,m), VT(n,n);
00160 lapack::gesvd('A','A', Ac, Sig, U, VT);
00161
00162
00163 double tol = std::numeric_limits<double>::epsilon()*maxDim*max(Sig);
00164
00165
00166
00167
00168
00169 SigI = zero_matrix<double>(n,m);
00170 for (int i=0;i<minDim;i++)
00171 {
00172 if (Sig(i) > tol)
00173 {
00174 SigI(i,i) = 1/Sig(i);
00175 }
00176 else
00177 {
00178 SigI(i,i) = 0;
00179 }
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189 matrix<double> temp = prod(trans(VT),SigI);
00190 return prod(temp,trans(U));
00191 }
00192
00193 bool select(double real, double imag)
00194 {
00195 if( real*real + imag*imag < 1) return 1;
00196 else return 0;
00197 }
00198
00199 matrix<double> dare(matrix<double> A, matrix<double> B, matrix<double> R,matrix<double>Q)
00200 {
00201
00202 int n=A.size1(),m=B.size2();
00203 matrix<double>Z11(n,n);
00204 matrix<double>Z12(n,n);
00205 matrix<double>Z21(n,n);
00206 matrix<double>Z22(n,n);
00207 matrix<double>G(n,n);
00208
00209 matrix<double>temp(n,n);
00210 temp=prod(pinv(R),trans(B));
00211 G=prod(B,temp);
00212 temp=prod(G,pinv(trans(A)));
00213 Z12=-temp;
00214 Z11=A+prod(temp,Q);
00215
00216 temp=trans(pinv(A));
00217 Z22=temp;
00218 Z21=prod(-temp,Q);
00219
00220
00221 matrix<double>Z(2*n,2*n);
00222 for (int i=0;i<2*n;i++)
00223 {
00224 for(int j=0;j<2*n;j++)
00225 {
00226 if (i<n && j<n)
00227 {
00228 Z(i,j)=Z11(i,j);
00229 }
00230 if (i>=n && j<n)
00231 {
00232 Z(i,j)=Z12(i-n,j);
00233 }
00234 if (i<n && j>=n)
00235 {
00236 Z(i,j)=Z21(i,j-n);
00237 }
00238 if (i>=n && j>=n)
00239 {
00240 Z(i,j)=Z21(i-n,j-n);
00241 }
00242 }
00243 }
00244
00245
00246 matrix<double>U(2*n,2*n);
00247 vector<double> eig(2*n);
00248
00249 traits::complex_d * w;
00250 traits::complex_d * vs;
00251 int sdim;
00252 traits::complex_d* work;
00253 double* rwork;
00254 bool * bwork;
00255 int info;
00256
00257
00258
00259 matrix<double>U11(n,n);
00260 matrix<double>U21(n,n);
00261 for(int i=0;i<n;i++)
00262 {
00263 for(int j=0;j<n;j++)
00264 {
00265 U11(i,j)=U(i,j);
00266 U21(i,j)=U(i,j+n);
00267 }
00268 }
00269
00270 return prod(U21,trans(U11));
00271 }
00272
00273 matrix<double> prod(matrix<double> A, matrix<double> B, matrix<double> C)
00274 {
00275 return prod(A, matrix<double> (prod(B,C)));
00276 }
00277
00278 void discretize(matrix<double>& Ac, matrix<double>& Bc, matrix<double>& Ad, matrix<double>& Bd, double T, int order)
00279 {
00280 Ad.resize(Ac.size1(), Ac.size2());
00281 Bd.resize(Bc.size1(), Bc.size2());
00282
00283 Ad = identity_matrix<double>(Ac.size1(), Ac.size2()) + T*Ac;
00284 Bd = T*Bc;
00285
00286 double T_power = T;
00287 matrix<double> Ac_power = Ac;
00288 int ifac = 1;
00289
00290 for (int i = 2; i <= order; i++)
00291 {
00292 T_power *= T;
00293 ifac *= ifac+1;
00294
00295 Bd = Bd + T_power/ifac * prod(Ac_power, Bc);
00296 Ac_power = prod(Ac_power, Ac);
00297 Ad = Ad + T_power/ifac * Ac_power;
00298
00299 }
00300
00301 }
00302
00303
00304 vector<double> integrate(vector<double> i1, vector<double> i0, vector<double> initial, double freq)
00305 {
00306 vector<double> ans;
00307 ans = (i0 + i1)/2;
00308 ans = ans/freq;
00309 ans = ans + initial;
00310 return ans;
00311 }
00312
00313
00314 double integrate (double i1, double i0, double initial, double freq)
00315 {
00316 double ans;
00317 ans = (i0 + i1) / 2;
00318 ans = ans/freq;
00319 ans = ans + initial ;
00320 return ans;
00321 }
00322
00323
00324 double elapsedTime(timeval time0, timeval time)
00325 {
00326 double timeElapsed = (time.tv_sec - time0.tv_sec);
00327 timeElapsed += (time.tv_usec - time0.tv_usec) / 1e6;
00328 return timeElapsed;
00329 }
00330
00331
00332 vector<double> quatProd(vector<
00333 double> q1, vector<double> q2)
00334 {
00335 vector<double> prod(4);
00336 prod(0) = (q1(0) * q2(0) - q1(1) * q2(1) - q1(2) * q2(2) - q1(3) * q2(3));
00337 prod(1) = (q1(0) * q2(1) + q1(1) * q2(0) + q1(2) * q2(3) - q1(3) * q2(2));
00338 prod(2) = (q1(0) * q2(2) - q1(1) * q2(3) + q1(2) * q2(0) + q1(3) * q2(1));
00339 prod(3) = (q1(0) * q2(3) + q1(1) * q2(2) - q1(2) * q2(1) + q1(3) * q2(0));
00340 return prod;
00341 }
00342
00343 vector<double> quatRotate(vector<double> q, vector<double> vec)
00344 {
00345 vector<double> vec4(4);
00346 vector<double> qConj(4);
00347 vector<double> vec4Rotated(4);
00348 vector<double> vec3Rotated(3);
00349 vec4(0) = 0;
00350 subrange(vec4, 1, 4) = subrange(vec, 0, 3);
00351 vec4Rotated = quatProd(q,vec4);
00352 qConj = quatConj(q);
00353 vec4Rotated = quatProd(vec4Rotated, qConj);
00354 subrange(vec3Rotated, 0, 3) = subrange(vec4Rotated, 1, 4);
00355 return vec3Rotated;
00356 }
00357
00358 vector<double> crossProd(vector<
00359 double> v1, vector<double> v2)
00360 {
00361 vector<double> prod(3);
00362 prod(0) = v1(1) * v2(2) - v1(2) * v2(1);
00363 prod(1) = v1(2) * v2(0) - v1(0) * v2(2);
00364 prod(2) = v1(0) * v2(1) - v1(1) * v2(0);
00365 return prod;
00366 }
00367
00368 vector<double> quatConj(vector<double> q)
00369 {
00370 vector<double> qConj(4);
00371 qConj(0) = q(0);
00372 qConj(1) = -q(1);
00373 qConj(2) = -q(2);
00374 qConj(3) = -q(3);
00375 return qConj;
00376 }
00377
00378 vector<double> quat2Euler(vector<double> q)
00379 {
00380 vector<double> eul(3);
00381 double roll, pitch, yaw;
00382 double sq0 = q(0) * q(0);
00383 double sq1 = q(1) * q(1);
00384 double sq2 = q(2) * q(2);
00385 double sq3 = q(3) * q(3);
00386 double test = q(0) * q(2) - q(3) * q(1);
00387
00388
00389 if (test > 0.499999)
00390 {
00391 yaw = 2 * atan2(q(1), q(0));
00392 pitch = M_PI / 2.;
00393 roll = 0;
00394
00395 }
00396 else if (test < -0.499999)
00397 {
00398 yaw = -2 * atan2(q(1), q(0));
00399 pitch = -M_PI / 2;
00400 roll = 0;
00401
00402 }
00403 else
00404 {
00405 roll = atan2(2 * (q(0) * q(1) + q(2) * q(3)), sq0 - sq1 - sq2 + sq3);
00406 pitch = asin(-2 * (q(1) * q(3) - q(0) * q(2)));
00407 yaw = atan2(2 * (q(1) * q(2) + q(0) * q(3)), sq0 + sq1 - sq2 - sq3);
00408 }
00409 eul(0) = roll;
00410 eul(1) = pitch;
00411 eul(2) = yaw;
00412 return eul;
00413 }
00414
00415 vector<double> euler2Quat(vector<double> euler)
00416 {
00417 vector<double> quat(4);
00418 double phi = euler(0), th = euler(1), gam = euler(2);
00419 quat(0) = cos(phi/2)*cos(th/2)*cos(gam/2)+sin(phi/2)*sin(th/2)*sin(gam/2);
00420 quat(1) = sin(phi/2)*cos(th/2)*cos(gam/2)-cos(phi/2)*sin(th/2)*sin(gam/2);
00421 quat(2) = cos(phi/2)*sin(th/2)*cos(gam/2)+sin(phi/2)*cos(th/2)*sin(gam/2);
00422 quat(3) = cos(phi/2)*cos(th/2)*sin(gam/2)+sin(phi/2)*sin(th/2)*cos(gam/2);
00423 return norm(quat);
00424 }
00425
00426 vector<double> axisAngle2Quat(vector<double> axis, double angle)
00427 {
00428 vector<double> quat(4);
00429
00430 quat(0) = cos(angle/2);
00431 quat(1) = sin(angle/2)*axis(0);
00432 quat(2) = sin(angle/2)*axis(1);
00433 quat(3) = sin(angle/2)*axis(2);
00434 return norm(quat);
00435 }
00436
00437 vector<double> norm(vector<double> vec)
00438 {
00439 double mag = norm_2(vec);
00440 if (mag == 0)
00441 {
00442 return zero_vector<double>(vec.size());
00443 }
00444 else
00445 {
00446 return vec*(1/norm_2(vec));
00447 }
00448 }
00449
00450
00451 }
00452