LCOV - code coverage report
Current view: directory - alg - thinplatespline.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 245 138 56.3 %
Date: 2010-01-09 Functions: 9 6 66.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: thinplatespline.cpp 15547 2008-10-17 17:45:03Z rouault $
       3                 :  *
       4                 :  * Project:  GDAL Warp API
       5                 :  * Purpose:  Implemenentation of 2D Thin Plate Spline transformer. 
       6                 :  * Author:   VIZRT Development Team.
       7                 :  *
       8                 :  * This code was provided by Gilad Ronnen (gro at visrt dot com) with 
       9                 :  * permission to reuse under the following license.
      10                 :  * 
      11                 :  ******************************************************************************
      12                 :  * Copyright (c) 2004, VIZRT Inc.
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  *
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  *
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      25                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  ****************************************************************************/
      32                 : 
      33                 : #include "thinplatespline.h"
      34                 : 
      35                 : #ifdef HAVE_FLOAT_H
      36                 : #  include <float.h>
      37                 : #elif defined(HAVE_VALUES_H)
      38                 : #  include <values.h>
      39                 : #endif
      40                 : 
      41                 : #ifndef FLT_MAX
      42                 : #  define FLT_MAX 1e+37
      43                 : #  define FLT_MIN 1e-37
      44                 : #endif
      45                 : 
      46                 : VizGeorefSpline2D* viz_xy2llz;
      47                 : VizGeorefSpline2D* viz_llz2xy;
      48                 : 
      49                 : /////////////////////////////////////////////////////////////////////////////////////
      50                 : //// vizGeorefSpline2D
      51                 : /////////////////////////////////////////////////////////////////////////////////////
      52                 : 
      53                 : #define A(r,c) _AA[ _nof_eqs * (r) + (c) ]
      54                 : #define Ainv(r,c) _Ainv[ _nof_eqs * (r) + (c) ]
      55                 : 
      56                 : 
      57                 : #define VIZ_GEOREF_SPLINE_DEBUG 0
      58                 : 
      59                 : int matrixInvert( int N, double input[], double output[] );
      60                 : 
      61              16 : void VizGeorefSpline2D::grow_points()
      62                 : 
      63                 : {
      64              16 :     int new_max = _max_nof_points*2 + 2 + 3;
      65                 :     int i;
      66                 :     
      67              16 :     if( _max_nof_points == 0 )
      68                 :     {
      69               8 :         x = (double *) VSIMalloc( sizeof(double) * new_max );
      70               8 :         y = (double *) VSIMalloc( sizeof(double) * new_max );
      71               8 :         u = (double *) VSIMalloc( sizeof(double) * new_max );
      72               8 :         unused = (int *) VSIMalloc( sizeof(int) * new_max );
      73               8 :         index = (int *) VSIMalloc( sizeof(int) * new_max );
      74              24 :         for( i = 0; i < VIZGEOREF_MAX_VARS; i++ )
      75                 :         {
      76              16 :             rhs[i] = (double *) VSICalloc( sizeof(double), new_max );
      77              16 :             coef[i] = (double *) VSICalloc( sizeof(double), new_max );
      78                 :         }
      79                 :     }
      80                 :     else
      81                 :     {
      82               8 :         x = (double *) VSIRealloc( x, sizeof(double) * new_max );
      83               8 :         y = (double *) VSIRealloc( y, sizeof(double) * new_max );
      84               8 :         u = (double *) VSIRealloc( u, sizeof(double) * new_max );
      85               8 :         unused = (int *) VSIRealloc( unused, sizeof(int) * new_max );
      86               8 :         index = (int *) VSIRealloc( index, sizeof(int) * new_max );
      87              24 :         for( i = 0; i < VIZGEOREF_MAX_VARS; i++ )
      88                 :         {
      89              16 :             rhs[i] = (double *) 
      90              16 :                 VSIRealloc( rhs[i], sizeof(double) * new_max );
      91              16 :             coef[i] = (double *) 
      92              16 :                 VSIRealloc( coef[i], sizeof(double) * new_max );
      93                 :         }
      94                 :     }
      95                 : 
      96              16 :     _max_nof_points = new_max - 3;
      97              16 : }
      98                 : 
      99              32 : int VizGeorefSpline2D::add_point( const double Px, const double Py, const double *Pvars )
     100                 : {
     101              32 :     type = VIZ_GEOREF_SPLINE_POINT_WAS_ADDED;
     102                 :     int i;
     103                 : 
     104              32 :     if( _nof_points == _max_nof_points )
     105               8 :         grow_points();
     106                 : 
     107              32 :     i = _nof_points;
     108                 :     //A new point is added
     109              32 :     x[i] = Px;
     110              32 :     y[i] = Py;
     111              96 :     for ( int j = 0; j < _nof_vars; j++ )
     112              64 :         rhs[j][i+3] = Pvars[j];
     113              32 :     _nof_points++;
     114              32 :     return 1;
     115                 : }
     116                 : 
     117               0 : bool VizGeorefSpline2D::change_point(int index, double Px, double Py, double* Pvars)
     118                 : {
     119               0 :     if ( index < _nof_points )
     120                 :     {
     121               0 :         int i = index;
     122               0 :         x[i] = Px;
     123               0 :         y[i] = Py;
     124               0 :         for ( int j = 0; j < _nof_vars; j++ )
     125               0 :             rhs[j][i+3] = Pvars[j];
     126                 :     }
     127                 : 
     128               0 :     return( true );
     129                 : }
     130                 : 
     131               0 : bool VizGeorefSpline2D::get_xy(int index, double& outX, double& outY)
     132                 : {
     133                 :     bool ok;
     134                 : 
     135               0 :     if ( index < _nof_points )
     136                 :     {
     137               0 :         ok = true;
     138               0 :         outX = x[index];
     139               0 :         outY = y[index];
     140                 :     }
     141                 :     else
     142                 :     {
     143               0 :         ok = false;
     144               0 :         outX = outY = 0.0f;
     145                 :     }
     146                 : 
     147               0 :     return(ok);
     148                 : }
     149                 : 
     150               0 : int VizGeorefSpline2D::delete_point(const double Px, const double Py )
     151                 : {
     152               0 :     for ( int i = 0; i < _nof_points; i++ )
     153                 :     {
     154               0 :         if ( ( fabs(Px - x[i]) <= _tx ) && ( fabs(Py - y[i]) <= _ty ) )
     155                 :         {
     156               0 :             for ( int j = i; j < _nof_points - 1; j++ )
     157                 :             {
     158               0 :                 x[j] = x[j+1];
     159               0 :                 y[j] = y[j+1];
     160               0 :                 for ( int k = 0; k < _nof_vars; k++ )
     161               0 :                     rhs[k][j+3] = rhs[k][j+3+1];
     162                 :             }
     163               0 :             _nof_points--;
     164               0 :             type = VIZ_GEOREF_SPLINE_POINT_WAS_DELETED;
     165               0 :             return(1);
     166                 :         }
     167                 :     }
     168               0 :     return(0);
     169                 : }
     170                 : 
     171               8 : int VizGeorefSpline2D::solve(void)
     172                 : {
     173                 :     int r, c, v;
     174                 :     int p;
     175                 :   
     176                 :     //  No points at all
     177               8 :     if ( _nof_points < 1 )
     178                 :     {
     179               0 :         type = VIZ_GEOREF_SPLINE_ZERO_POINTS;
     180               0 :         return(0);
     181                 :     }
     182                 :   
     183                 :     // Only one point
     184               8 :     if ( _nof_points == 1 )
     185                 :     {
     186               0 :         type = VIZ_GEOREF_SPLINE_ONE_POINT;
     187               0 :         return(1);
     188                 :     }
     189                 :     // Just 2 points - it is necessarily 1D case
     190               8 :     if ( _nof_points == 2 )
     191                 :     {
     192               0 :         _dx = x[1] - x[0];
     193               0 :         _dy = y[1] - y[0];   
     194               0 :         double fact = 1.0 / ( _dx * _dx + _dy * _dy );
     195               0 :         _dx *= fact;
     196               0 :         _dy *= fact;
     197                 :     
     198               0 :         type = VIZ_GEOREF_SPLINE_TWO_POINTS;
     199               0 :         return(2);
     200                 :     }
     201                 :   
     202                 :     // More than 2 points - first we have to check if it is 1D or 2D case
     203                 :     
     204               8 :     double xmax = x[0], xmin = x[0], ymax = y[0], ymin = y[0];
     205                 :     double delx, dely;
     206                 :     double xx, yy;
     207               8 :     double sumx = 0.0f, sumy= 0.0f, sumx2 = 0.0f, sumy2 = 0.0f, sumxy = 0.0f;
     208                 :     double SSxx, SSyy, SSxy;
     209                 :   
     210              40 :     for ( p = 0; p < _nof_points; p++ )
     211                 :     {
     212              32 :         xx = x[p];
     213              32 :         yy = y[p];
     214                 :     
     215              32 :         xmax = MAX( xmax, xx );
     216              32 :         xmin = MIN( xmin, xx );
     217              32 :         ymax = MAX( ymax, yy );
     218              32 :         ymin = MIN( ymin, yy );
     219                 :     
     220              32 :         sumx  += xx;
     221              32 :         sumx2 += xx * xx;
     222              32 :         sumy  += yy;
     223              32 :         sumy2 += yy * yy;
     224              32 :         sumxy += xx * yy;
     225                 :     }
     226               8 :     delx = xmax - xmin;
     227               8 :     dely = ymax - ymin;
     228                 :   
     229               8 :     SSxx = sumx2 - sumx * sumx / _nof_points;
     230               8 :     SSyy = sumy2 - sumy * sumy / _nof_points;
     231               8 :     SSxy = sumxy - sumx * sumy / _nof_points;
     232                 :   
     233               8 :     if ( delx < 0.001 * dely || dely < 0.001 * delx || 
     234                 :          fabs ( SSxy * SSxy / ( SSxx * SSyy ) ) > 0.99 )
     235                 :     {
     236                 :         int p1;
     237                 :     
     238               0 :         type = VIZ_GEOREF_SPLINE_ONE_DIMENSIONAL;
     239                 :     
     240               0 :         _dx = _nof_points * sumx2 - sumx * sumx;
     241               0 :         _dy = _nof_points * sumy2 - sumy * sumy;
     242               0 :         double fact = 1.0 / sqrt( _dx * _dx + _dy * _dy );
     243               0 :         _dx *= fact;
     244               0 :         _dy *= fact;
     245                 :     
     246               0 :         for ( p = 0; p < _nof_points; p++ )
     247                 :         {
     248               0 :             double dxp = x[p] - x[0];
     249               0 :             double dyp = y[p] - y[0];
     250               0 :             u[p] = _dx * dxp + _dy * dyp;
     251               0 :             unused[p] = 1;
     252                 :         }
     253                 :     
     254               0 :         for ( p = 0; p < _nof_points; p++ )
     255                 :         {
     256               0 :             int min_index = -1;
     257               0 :             double min_u = 0;
     258               0 :             for ( p1 = 0; p1 < _nof_points; p1++ )
     259                 :             {
     260               0 :                 if ( unused[p1] )
     261                 :                 {
     262               0 :                     if ( min_index < 0 || u[p1] < min_u )
     263                 :                     {
     264               0 :                         min_index = p1;
     265               0 :                         min_u = u[p1];
     266                 :                     }
     267                 :                 }
     268                 :             }
     269               0 :             index[p] = min_index;
     270               0 :             unused[min_index] = 0;
     271                 :         }
     272                 :     
     273               0 :         return(3);
     274                 :     }
     275                 :   
     276               8 :     type = VIZ_GEOREF_SPLINE_FULL;
     277                 :     // Make the necessary memory allocations
     278               8 :     if ( _AA )
     279               0 :         CPLFree(_AA);
     280               8 :     if ( _Ainv )
     281               0 :         CPLFree(_Ainv);
     282                 :   
     283               8 :     _nof_eqs = _nof_points + 3;
     284                 :   
     285               8 :     _AA = ( double * )CPLCalloc( _nof_eqs * _nof_eqs, sizeof( double ) );
     286               8 :     _Ainv = ( double * )CPLCalloc( _nof_eqs * _nof_eqs, sizeof( double ) );
     287                 :   
     288                 :     // Calc the values of the matrix A
     289              32 :     for ( r = 0; r < 3; r++ )
     290              96 :         for ( c = 0; c < 3; c++ )
     291              72 :             A(r,c) = 0.0;
     292                 :     
     293              40 :     for ( c = 0; c < _nof_points; c++ )
     294                 :     {
     295              32 :         A(0,c+3) = 1.0;
     296              32 :         A(1,c+3) = x[c];
     297              32 :         A(2,c+3) = y[c];
     298                 :       
     299              32 :         A(c+3,0) = 1.0;
     300              32 :         A(c+3,1) = x[c];
     301              32 :         A(c+3,2) = y[c];
     302                 :     }
     303                 :     
     304              40 :     for ( r = 0; r < _nof_points; r++ )
     305             112 :         for ( c = r; c < _nof_points; c++ )
     306                 :         {
     307              80 :             A(r+3,c+3) = base_func( x[r], y[r], x[c], y[c] );
     308              80 :             if ( r != c )
     309              48 :                 A(c+3,r+3 ) = A(r+3,c+3);
     310                 :         }
     311                 :       
     312                 : #if VIZ_GEOREF_SPLINE_DEBUG
     313                 :       
     314                 :     for ( r = 0; r < _nof_eqs; r++ )
     315                 :     {
     316                 :         for ( c = 0; c < _nof_eqs; c++ )
     317                 :             fprintf(stderr, "%f", A(r,c));
     318                 :         fprintf(stderr, "\n");
     319                 :     }
     320                 :       
     321                 : #endif
     322                 :       
     323                 :     // Invert the matrix
     324               8 :     int status = matrixInvert( _nof_eqs, _AA, _Ainv );
     325                 :       
     326               8 :     if ( !status )
     327                 :     {
     328               0 :         fprintf(stderr, " There is a problem to invert the interpolation matrix\n");
     329               0 :         return 0;
     330                 :     }
     331                 :       
     332                 :     // calc the coefs
     333              24 :     for ( v = 0; v < _nof_vars; v++ )
     334             128 :         for ( r = 0; r < _nof_eqs; r++ )
     335                 :         {
     336             112 :             coef[v][r] = 0.0;
     337             896 :             for ( c = 0; c < _nof_eqs; c++ )
     338             784 :                 coef[v][r] += Ainv(r,c) * rhs[v][c];
     339                 :         }
     340                 :         
     341               8 :     return(4);
     342                 : }
     343                 : 
     344            1725 : int VizGeorefSpline2D::get_point( const double Px, const double Py, double *vars )
     345                 : {
     346                 :   int v, r;
     347                 :   double tmp, Pu;
     348                 :   double fact;
     349            1725 :   int leftP=0, rightP=0, found = 0;
     350                 :   
     351            1725 :   switch ( type )
     352                 :   {
     353                 :   case VIZ_GEOREF_SPLINE_ZERO_POINTS :
     354               0 :     for ( v = 0; v < _nof_vars; v++ )
     355               0 :       vars[v] = 0.0;
     356               0 :     break;
     357                 :   case VIZ_GEOREF_SPLINE_ONE_POINT :
     358               0 :     for ( v = 0; v < _nof_vars; v++ )
     359               0 :       vars[v] = rhs[v][3];
     360               0 :     break;
     361                 :   case VIZ_GEOREF_SPLINE_TWO_POINTS :
     362               0 :     fact = _dx * ( Px - x[0] ) + _dy * ( Py - y[0] );
     363               0 :     for ( v = 0; v < _nof_vars; v++ )
     364               0 :       vars[v] = ( 1 - fact ) * rhs[v][3] + fact * rhs[v][4];
     365               0 :     break;
     366                 :   case VIZ_GEOREF_SPLINE_ONE_DIMENSIONAL :
     367               0 :     Pu = _dx * ( Px - x[0] ) + _dy * ( Py - y[0] );
     368               0 :     if ( Pu <= u[index[0]] )
     369                 :     {
     370               0 :       leftP = index[0];
     371               0 :       rightP = index[1];
     372                 :     }
     373               0 :     else if ( Pu >= u[index[_nof_points-1]] )
     374                 :     {
     375               0 :       leftP = index[_nof_points-2];
     376               0 :       rightP = index[_nof_points-1];
     377                 :     }
     378                 :     else
     379                 :     {
     380               0 :       for ( r = 1; !found && r < _nof_points; r++ )
     381                 :       {
     382               0 :         leftP = index[r-1];
     383               0 :         rightP = index[r];          
     384               0 :         if ( Pu >= u[leftP] && Pu <= u[rightP] )
     385               0 :           found = 1;
     386                 :       }
     387                 :     }
     388                 :     
     389               0 :     fact = ( Pu - u[leftP] ) / ( u[rightP] - u[leftP] );
     390               0 :     for ( v = 0; v < _nof_vars; v++ )
     391               0 :       vars[v] = ( 1.0 - fact ) * rhs[v][leftP+3] +
     392               0 :       fact * rhs[v][rightP+3];
     393               0 :     break;
     394                 :   case VIZ_GEOREF_SPLINE_FULL :
     395            5175 :     for ( v = 0; v < _nof_vars; v++ )
     396            3450 :       vars[v] = coef[v][0] + coef[v][1] * Px + coef[v][2] * Py;
     397                 :     
     398            8625 :     for ( r = 0; r < _nof_points; r++ )
     399                 :     {
     400            6900 :       tmp = base_func( Px, Py, x[r], y[r] );
     401           20700 :       for ( v= 0; v < _nof_vars; v++ )
     402           13800 :         vars[v] += coef[v][r+3] * tmp;
     403                 :     }
     404            1725 :     break;
     405                 :   case VIZ_GEOREF_SPLINE_POINT_WAS_ADDED :
     406               0 :     fprintf(stderr, " A point was added after the last solve\n");
     407               0 :     fprintf(stderr, " NO interpolation - return values are zero\n");
     408               0 :     for ( v = 0; v < _nof_vars; v++ )
     409               0 :       vars[v] = 0.0;
     410               0 :     return(0);
     411                 :     break;
     412                 :   case VIZ_GEOREF_SPLINE_POINT_WAS_DELETED :
     413               0 :     fprintf(stderr, " A point was deleted after the last solve\n");
     414               0 :     fprintf(stderr, " NO interpolation - return values are zero\n");
     415               0 :     for ( v = 0; v < _nof_vars; v++ )
     416               0 :       vars[v] = 0.0;
     417               0 :     return(0);
     418                 :     break;
     419                 :   default :
     420               0 :     return(0);
     421                 :     break;
     422                 :   }
     423            1725 :   return(1);
     424                 : }
     425                 : 
     426            6980 : double VizGeorefSpline2D::base_func( const double x1, const double y1,
     427                 :               const double x2, const double y2 )
     428                 : {
     429            6980 :   if ( ( x1 == x2 ) && (y1 == y2 ) )
     430              48 :     return 0.0;
     431                 :   
     432            6932 :   double dist  = ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 );
     433                 :   
     434            6932 :   return dist * log( dist );  
     435                 : }
     436                 : 
     437               8 : int matrixInvert( int N, double input[], double output[] )
     438                 : {
     439                 :     // Receives an array of dimension NxN as input.  This is passed as a one-
     440                 :     // dimensional array of N-squared size.  It produces the inverse of the
     441                 :     // input matrix, returned as output, also of size N-squared.  The Gauss-
     442                 :     // Jordan Elimination method is used.  (Adapted from a BASIC routine in
     443                 :     // "Basic Scientific Subroutines Vol. 1", courtesy of Scott Edwards.)
     444                 :   
     445                 :     // Array elements 0...N-1 are for the first row, N...2N-1 are for the
     446                 :     // second row, etc.
     447                 :   
     448                 :     // We need to have a temporary array of size N x 2N.  We'll refer to the
     449                 :     // "left" and "right" halves of this array.
     450                 :   
     451                 :     int row, col;
     452                 :   
     453                 : #if 0
     454                 :     fprintf(stderr, "Matrix Inversion input matrix (N=%d)\n", N);
     455                 :     for ( row=0; row<N; row++ )
     456                 :     {
     457                 :         for ( col=0; col<N; col++ )
     458                 :         {
     459                 :             fprintf(stderr, "%5.2f ", input[row*N + col ]  );
     460                 :         }
     461                 :         fprintf(stderr, "\n");
     462                 :     }
     463                 : #endif
     464                 :   
     465               8 :     int tempSize = 2 * N * N;
     466               8 :     double* temp = (double*) new double[ tempSize ];
     467                 :     double ftemp;
     468                 :   
     469               8 :     if (temp == 0) {
     470                 :     
     471               0 :         fprintf(stderr, "matrixInvert(): ERROR - memory allocation failed.\n");
     472               0 :         return false;
     473                 :     }
     474                 :   
     475                 :     // First create a double-width matrix with the input array on the left
     476                 :     // and the identity matrix on the right.
     477                 :   
     478              64 :     for ( row=0; row<N; row++ )
     479                 :     {
     480             448 :         for ( col=0; col<N; col++ )
     481                 :         {
     482                 :             // Our index into the temp array is X2 because it's twice as wide
     483                 :             // as the input matrix.
     484                 :       
     485             392 :             temp[ 2*row*N + col ] = input[ row*N+col ]; // left = input matrix
     486             392 :             temp[ 2*row*N + col + N ] = 0.0f;     // right = 0
     487                 :         }
     488              56 :         temp[ 2*row*N + row + N ] = 1.0f;   // 1 on the diagonal of RHS
     489                 :     }
     490                 :   
     491                 :     // Now perform row-oriented operations to convert the left hand side
     492                 :     // of temp to the identity matrix.  The inverse of input will then be
     493                 :     // on the right.
     494                 :   
     495                 :     int max;
     496               8 :     int k=0;
     497              64 :     for (k = 0; k < N; k++)
     498                 :     {
     499              56 :         if (k+1 < N) // if not on the last row
     500                 :         {              
     501              48 :             max = k;
     502             216 :             for (row = k+1; row < N; row++) // find the maximum element
     503                 :             {  
     504             168 :                 if (fabs( temp[row*2*N + k] ) > fabs( temp[max*2*N + k] ))
     505                 :                 {
     506              44 :                     max = row;
     507                 :                 }
     508                 :             }
     509                 :       
     510              48 :             if (max != k) // swap all the elements in the two rows
     511                 :             {        
     512             506 :                 for (col=k; col<2*N; col++)
     513                 :                 {
     514             467 :                     ftemp = temp[k*2*N + col];
     515             467 :                     temp[k*2*N + col] = temp[max*2*N + col];
     516             467 :                     temp[max*2*N + col] = ftemp;
     517                 :                 }
     518                 :             }
     519                 :         }
     520                 :     
     521              56 :         ftemp = temp[ k*2*N + k ];
     522              56 :         if ( ftemp == 0.0f ) // matrix cannot be inverted
     523                 :         {
     524               0 :             delete[] temp;
     525               0 :             return false;
     526                 :         }
     527                 :     
     528             672 :         for ( col=k; col<2*N; col++ )
     529                 :         {
     530             616 :             temp[ k*2*N + col ] /= ftemp;
     531                 :         }
     532                 :     
     533             448 :         for ( row=0; row<N; row++ )
     534                 :         {
     535             392 :             if ( row != k )
     536                 :             {
     537             336 :                 ftemp = temp[ row*2*N + k ];
     538            4032 :                 for ( col=k; col<2*N; col++ ) 
     539                 :                 {
     540            3696 :                     temp[ row*2*N + col ] -= ftemp * temp[ k*2*N + col ];
     541                 :                 }
     542                 :             }
     543                 :         }
     544                 :     }
     545                 :   
     546                 :     // Retrieve inverse from the right side of temp
     547                 :   
     548              64 :     for (row = 0; row < N; row++)
     549                 :     {
     550             448 :         for (col = 0; col < N; col++)
     551                 :         {
     552             392 :             output[row*N + col] = temp[row*2*N + col + N ];
     553                 :         }
     554                 :     }
     555                 :   
     556                 : #if 0
     557                 :     fprintf(stderr, "Matrix Inversion result matrix:\n");
     558                 :     for ( row=0; row<N; row++ )
     559                 :     {
     560                 :         for ( col=0; col<N; col++ )
     561                 :         {
     562                 :             fprintf(stderr, "%5.2f ", output[row*N + col ]  );
     563                 :         }
     564                 :         fprintf(stderr, "\n");
     565                 :     }
     566                 : #endif
     567                 :   
     568               8 :     delete [] temp;       // free memory
     569               8 :     return true;
     570                 : }

Generated by: LCOV version 1.7