00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "CeylanMatrix2.h"
00028
00029
00030 #include "CeylanBipoint.h"
00031 #include "CeylanVector2.h"
00032
00033 #include "CeylanEndomorphism.h"
00034
00035 #include "CeylanLogPlug.h"
00036 #include "CeylanOperators.h"
00037
00038
00039 #ifdef CEYLAN_USES_CONFIG_H
00040 #include "CeylanConfig.h"
00041 #endif // CEYLAN_USES_CONFIG_H
00042
00043
00044 #include <iostream>
00045 using std::endl ;
00046
00047 #include <sstream>
00048 using std::ostringstream ;
00049
00050 #include <iomanip>
00051
00052
00053
00054 using std::string ;
00055
00056
00057 using namespace Ceylan ;
00058 using namespace Ceylan::Maths ;
00059 using namespace Ceylan::Maths::Linear ;
00060
00061
00062 using Ceylan::Maths::Real ;
00063
00064
00065
00066 Matrix2::Matrix2( Real x0, Real x1, Real y0, Real y1 )
00067 {
00068
00069 _mat[0][0] = x0 ;
00070 _mat[1][0] = x1 ;
00071 _mat[0][1] = y0 ;
00072 _mat[1][1] = y1 ;
00073
00074 }
00075
00076
00077
00078 Matrix2::Matrix2( const Matrix2 & source ) :
00079 Matrix()
00080 {
00081
00082 for ( MatrixIndex j = 0 ; j < Dimensions ; j++ )
00083 for ( MatrixIndex i = 0 ; i < Dimensions ; i++ )
00084 _mat[i][j] = source._mat[i][j] ;
00085
00086 }
00087
00088
00089
00090 Matrix2::~Matrix2() throw()
00091 {
00092
00093 }
00094
00095
00096
00097 void Matrix2::setTo( Real x0, Real x1, Real y0, Real y1 )
00098 {
00099
00100 _mat[0][0] = x0 ;
00101 _mat[1][0] = x1 ;
00102 _mat[0][1] = y0 ;
00103 _mat[1][1] = y1 ;
00104
00105 }
00106
00107
00108
00109 void Matrix2::setColumn( MatrixIndex columnNumber, const Vector2 & newColumn )
00110 {
00111
00112 for ( MatrixIndex i = 0 ; i < Dimensions ; i++ )
00113 _mat[columnNumber][i] = newColumn._vec[i] ;
00114
00115 }
00116
00117
00118
00119 void Matrix2::setAllElementsTo( Real commonValue )
00120 {
00121
00122 for ( MatrixIndex j = 0 ; j < Dimensions ; j++ )
00123 for ( MatrixIndex i = 0 ; i < Dimensions ; i++ )
00124 _mat[i][j] = commonValue ;
00125
00126 }
00127
00128
00129
00130 Real Matrix2::getElementAt( MatrixIndex abscissa, MatrixIndex ordinate ) const
00131 {
00132
00133 #if CEYLAN_DEBUG
00134
00135 if ( abscissa >= Dimensions || ordinate >= Dimensions )
00136 throw MathsException( "Matrix2::getElementAt: index out of bounds." ) ;
00137
00138 #endif // CEYLAN_DEBUG
00139
00140 return _mat[ abscissa ][ ordinate ] ;
00141
00142 }
00143
00144
00145
00146 void Matrix2::setElementAt( MatrixIndex abscissa,
00147 MatrixIndex ordinate, Real newValue )
00148 {
00149
00150 #if CEYLAN_DEBUG
00151
00152 if ( abscissa >= Dimensions || ordinate >= Dimensions )
00153 throw MathsException( "Matrix2::setElementAt: index out of bounds." ) ;
00154
00155 #endif // CEYLAN_DEBUG
00156
00157 _mat[ abscissa ][ ordinate ] = newValue ;
00158
00159 }
00160
00161
00162
00163 void Matrix2::setToIdentity()
00164 {
00165
00166 setToDiagonal( 1 ) ;
00167
00168 }
00169
00170
00171 void Matrix2::setToDiagonal( Real diagonalTerm )
00172 {
00173
00174 for ( MatrixIndex j = 0 ; j < Dimensions ; j++ )
00175 for ( MatrixIndex i = 0 ; i < Dimensions ; i++ )
00176 _mat[i][j] = ( (i==j) ? diagonalTerm: 0 ) ;
00177
00178 }
00179
00180
00181
00182 void Matrix2::transpose()
00183 {
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 Real temp ;
00197
00198 for ( MatrixIndex j = 0 ; j < Dimensions ; j++ )
00199 for ( MatrixIndex i = j+1 ; i < Dimensions ; i++ )
00200 {
00201 temp = _mat[j][i] ;
00202 _mat[j][i] = _mat[i][j] ;
00203 _mat[i][j] = temp ;
00204 }
00205
00206 }
00207
00208
00209
00210 Real Matrix2::trace() const
00211 {
00212
00213 Real sum = 0 ;
00214
00215 for ( MatrixIndex i = 0 ; i < Dimensions ; i++ )
00216 sum += _mat[i][i] ;
00217
00218 return sum ;
00219
00220 }
00221
00222
00223
00224 Real Matrix2::determinant() const
00225 {
00226
00227
00228 return _mat[0][0] * _mat[1][1] - _mat[0][1] * _mat[1][0] ;
00229
00230 }
00231
00232
00233
00234 const string Matrix2::toString( VerbosityLevels level ) const
00235 {
00236
00237 string res ;
00238
00239 if ( TextDisplayable::GetOutputFormat() == TextDisplayable::html )
00240 {
00241
00242 res = "<table border=1>" ;
00243
00244 for ( MatrixIndex j = 0; j < Dimensions; j++ )
00245 {
00246 res += " <tr>\n" ;
00247
00248 for ( MatrixIndex i = 0; i < Dimensions; i++ )
00249 res += " <td>" + Ceylan::toString( _mat[i][j] )
00250 + "</td>" ;
00251
00252 res += " </tr>\n" ;
00253 }
00254
00255 res += "</table>" ;
00256
00257
00258 return res ;
00259 }
00260
00261
00262
00263 ostringstream oss ;
00264
00265 oss.precision( Ceylan::DigitOutputPrecision ) ;
00266
00267 oss << endl ;
00268
00269 for ( MatrixIndex j = 0; j < Dimensions; j++ )
00270 for ( MatrixIndex i = 0; i < Dimensions; i++ )
00271 oss << ( ( i == 0 ) ? "[ ": " " )
00272 << std::setw(5)
00273 << _mat[i][j]
00274 << ( ( i== Dimensions-1 ) ? " ]\n": " ") ;
00275 oss << endl ;
00276
00277 res = oss.str() ;
00278
00279
00280 #if CEYLAN_DEBUG
00281
00282 if ( oss.fail() )
00283 {
00284 string message = "Matrix2::toString: conversion error." ;
00285 Log::LogPlug::error( message ) ;
00286 return message ;
00287 }
00288
00289 #endif // CEYLAN_DEBUG
00290
00291 return res ;
00292
00293 }
00294
00295
00296
00297 Matrix2 Matrix2::Cofactor( const Matrix2 & m )
00298 {
00299
00300 Matrix2 result ;
00301
00302 result._mat[0][0] = m._mat[1][1] ;
00303 result._mat[1][0] = - m._mat[0][1] ;
00304 result._mat[0][1] = - m._mat[1][0] ;
00305 result._mat[1][1] = m._mat[0][0] ;
00306
00307 return result ;
00308
00309 }
00310
00311
00312
00313 Matrix2 Matrix2::Adjoint( const Matrix2 & m )
00314 {
00315
00316 Matrix2 result = Cofactor( m ) ;
00317 result.transpose() ;
00318 return result ;
00319
00320
00321
00322 }
00323
00324
00325
00326 Matrix2 Matrix2::CreateFromRotation( AngleInDegrees angle )
00327 {
00328
00329 return CreateFrom( Linear::Rotation2DFunctor( angle ) ) ;
00330
00331 }
00332
00333
00334
00335 bool Ceylan::Maths::Linear::operator == ( const Matrix2 & m1,
00336 const Matrix2 & m2 )
00337 {
00338
00339 for ( MatrixIndex j = 0; j < Matrix2::Dimensions; j++ )
00340 for ( MatrixIndex i = 0; i < Matrix2::Dimensions; i++ )
00341 {
00342 if ( ! AreRelativelyEqual<Real>( m1._mat[i][j],
00343 m2._mat[i][j] ) )
00344 return false ;
00345 }
00346
00347 return true ;
00348
00349 }
00350
00351
00352
00353 bool Ceylan::Maths::Linear::operator != ( const Matrix2 & m1,
00354 const Matrix2 & m2 )
00355 {
00356
00357 return ( ! ( m1 == m2 ) ) ;
00358
00359 }
00360
00361
00362
00363 Matrix2 Ceylan::Maths::Linear::operator + ( const Matrix2 & m1,
00364 const Matrix2 & m2 )
00365 {
00366
00367 Matrix2 result ;
00368
00369 for ( MatrixIndex j = 0; j < Matrix2::Dimensions; j++ )
00370 for ( MatrixIndex i = 0; i < Matrix2::Dimensions; i++ )
00371 result._mat[i][j] = m1._mat[i][j] + m2._mat[i][j] ;
00372
00373 return result ;
00374
00375 }
00376
00377
00378
00379 Matrix2 Ceylan::Maths::Linear::operator - ( const Matrix2 & m1,
00380 const Matrix2 & m2 )
00381 {
00382
00383 Matrix2 result ;
00384
00385 for ( MatrixIndex j = 0; j < Matrix2::Dimensions; j++ )
00386 for ( MatrixIndex i = 0; i < Matrix2::Dimensions; i++ )
00387 result._mat[i][j] = m1._mat[i][j] - m2._mat[i][j] ;
00388
00389 return result ;
00390
00391 }
00392
00393
00394
00395 Matrix2 Ceylan::Maths::Linear::operator * ( const Matrix2 & m1,
00396 const Matrix2 & m2 )
00397 {
00398
00399 Matrix2 result ;
00400
00401 for ( MatrixIndex j = 0; j < Matrix2::Dimensions; j++ )
00402 for ( MatrixIndex i = 0; i < Matrix2::Dimensions; i++ )
00403 for ( MatrixIndex k = 0; k < Matrix2::Dimensions; k++ )
00404 result._mat[i][j] += m1._mat[k][j] * m2._mat[i][k] ;
00405
00406 return result ;
00407
00408 }
00409
00410
00411
00412 Matrix2 Ceylan::Maths::Linear::operator * ( Real lambda, const Matrix2 & m )
00413 {
00414
00415 Matrix2 result ;
00416
00417 for ( MatrixIndex j = 0; j < Matrix2::Dimensions; j++ )
00418 for ( MatrixIndex i = 0; i < Matrix2::Dimensions; i++ )
00419 result._mat[i][j] = lambda * m._mat[i][j] ;
00420
00421 return result ;
00422
00423 }
00424
00425
00426
00427 Matrix2 Ceylan::Maths::Linear::operator ! ( const Matrix2 & m )
00428 {
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 Real d = m.determinant() ;
00441
00442 if ( ! IsNull( d ) )
00443 return (1/d) * ~ Matrix2::Cofactor( m ) ;
00444 else
00445 throw LinearException(
00446 "Matrix2: inverse operator ('!'): singular matrix." ) ;
00447
00448 }
00449
00450
00451
00452 Matrix2 Ceylan::Maths::Linear::operator ~ ( const Matrix2 & m )
00453 {
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464 Matrix2 result( m ) ;
00465
00466 result.transpose() ;
00467
00468 return result ;
00469
00470 }
00471