mathop.c
Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2014 Andrea Vedaldi.
00008 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00261 /* ---------------------------------------------------------------- */
00262 #ifndef VL_MATHOP_INSTANTIATING
00263 
00264 #include "mathop.h"
00265 #include "mathop_sse2.h"
00266  #include "mathop_avx.h"
00267 #include <math.h>
00268 
00269 #undef FLT
00270 #define FLT VL_TYPE_FLOAT
00271 #define VL_MATHOP_INSTANTIATING
00272 #include "mathop.c"
00273 
00274 #undef FLT
00275 #define FLT VL_TYPE_DOUBLE
00276 #define VL_MATHOP_INSTANTIATING
00277 #include "mathop.c"
00278 #endif
00279 
00280 /* ---------------------------------------------------------------- */
00281 #ifdef VL_MATHOP_INSTANTIATING
00282 #include "float.th"
00283 
00284 #undef COMPARISONFUNCTION_TYPE
00285 #undef COMPARISONFUNCTION3_TYPE
00286 #if (FLT == VL_TYPE_FLOAT)
00287 #  define COMPARISONFUNCTION_TYPE VlFloatVectorComparisonFunction
00288 #  define COMPARISONFUNCTION3_TYPE VlFloatVector3ComparisonFunction
00289 #else
00290 #  define COMPARISONFUNCTION_TYPE VlDoubleVectorComparisonFunction
00291 #  define COMPARISONFUNCTION3_TYPE VlDoubleVector3ComparisonFunction
00292 #endif
00293 
00294 /* ---------------------------------------------------------------- */
00295 
00296 VL_EXPORT T
00297 VL_XCAT(_vl_distance_l2_, SFX)
00298 (vl_size dimension, T const * X, T const * Y)
00299 {
00300   T const * X_end = X + dimension ;
00301   T acc = 0.0 ;
00302   while (X < X_end) {
00303     T d = *X++ - *Y++ ;
00304     acc += d * d ;
00305   }
00306   return acc ;
00307 }
00308 
00309 VL_EXPORT T
00310 VL_XCAT(_vl_distance_l1_, SFX)
00311 (vl_size dimension, T const * X, T const * Y)
00312 {
00313   T const * X_end = X + dimension ;
00314   T acc = 0.0 ;
00315   while (X < X_end) {
00316     T d = *X++ - *Y++ ;
00317     acc += VL_MAX(d, -d) ;
00318   }
00319   return acc ;
00320 }
00321 
00322 VL_EXPORT T
00323 VL_XCAT(_vl_distance_chi2_, SFX)
00324 (vl_size dimension, T const * X, T const * Y)
00325 {
00326   T const * X_end = X + dimension ;
00327   T acc = 0.0 ;
00328   while (X < X_end) {
00329     T a = *X++ ;
00330     T b = *Y++ ;
00331     T delta = a - b ;
00332     T denom = (a + b) ;
00333     T numer = delta * delta ;
00334     if (denom) {
00335       T ratio = numer / denom ;
00336       acc += ratio ;
00337     }
00338   }
00339   return acc ;
00340 }
00341 
00342 VL_EXPORT T
00343 VL_XCAT(_vl_distance_hellinger_, SFX)
00344 (vl_size dimension, T const * X, T const * Y)
00345 {
00346   T const * X_end = X + dimension ;
00347   T acc = 0.0 ;
00348   while (X < X_end) {
00349     T a = *X++ ;
00350     T b = *Y++ ;
00351 #if (FLT == VL_TYPE_FLOAT)
00352     acc += a + b - 2.0 * sqrtf (a*b) ;
00353 #else
00354     acc += a + b - 2.0 * sqrt (a*b) ;
00355 #endif
00356   }
00357   return acc ;
00358 }
00359 
00360 VL_EXPORT T
00361 VL_XCAT(_vl_distance_js_, SFX)
00362 (vl_size dimension, T const * X, T const * Y)
00363 {
00364   T const * X_end = X + dimension ;
00365   T acc = 0.0 ;
00366   while (X < X_end) {
00367     T x = *X++ ;
00368     T y = *Y++ ;
00369     if (x) acc += x - x * VL_XCAT(vl_log2_,SFX)(1 + y/x) ;
00370     if (y) acc += y - y * VL_XCAT(vl_log2_,SFX)(1 + x/y) ;
00371   }
00372   return acc ;
00373 }
00374 
00375 VL_EXPORT T
00376 VL_XCAT(_vl_kernel_l2_, SFX)
00377 (vl_size dimension, T const * X, T const * Y)
00378 {
00379   T const * X_end = X + dimension ;
00380   T acc = 0.0 ;
00381   while (X < X_end) {
00382     T a = *X++ ;
00383     T b = *Y++ ;
00384     acc += a * b ;
00385   }
00386   return acc ;
00387 }
00388 
00389 VL_EXPORT T
00390 VL_XCAT(_vl_kernel_l1_, SFX)
00391 (vl_size dimension, T const * X, T const * Y)
00392 {
00393   T const * X_end = X + dimension ;
00394   T acc = 0.0 ;
00395   while (X < X_end) {
00396     T a = *X++ ;
00397     T b = *Y++ ;
00398     T a_ = VL_XCAT(vl_abs_, SFX) (a) ;
00399     T b_ = VL_XCAT(vl_abs_, SFX) (b) ;
00400     acc += a_ + b_ - VL_XCAT(vl_abs_, SFX) (a - b) ;
00401   }
00402   return acc / ((T)2) ;
00403 }
00404 
00405 VL_EXPORT T
00406 VL_XCAT(_vl_kernel_chi2_, SFX)
00407 (vl_size dimension, T const * X, T const * Y)
00408 {
00409   T const * X_end = X + dimension ;
00410   T acc = 0.0 ;
00411   while (X < X_end) {
00412     T a = *X++ ;
00413     T b = *Y++ ;
00414     T denom = (a + b) ;
00415     if (denom) {
00416       T numer = 2 * a * b ;
00417       T ratio = numer / denom ;
00418       acc += ratio ;
00419     }
00420   }
00421   return acc ;
00422 }
00423 
00424 VL_EXPORT T
00425 VL_XCAT(_vl_kernel_hellinger_, SFX)
00426 (vl_size dimension, T const * X, T const * Y)
00427 {
00428   T const * X_end = X + dimension ;
00429   T acc = 0.0 ;
00430   while (X < X_end) {
00431     T a = *X++ ;
00432     T b = *Y++ ;
00433 #if (FLT == VL_TYPE_FLOAT)
00434     acc += sqrtf (a*b) ;
00435 #else
00436     acc += sqrt (a*b) ;
00437 #endif
00438   }
00439   return acc ;
00440 }
00441 
00442 VL_EXPORT T
00443 VL_XCAT(_vl_kernel_js_, SFX)
00444 (vl_size dimension, T const * X, T const * Y)
00445 {
00446   T const * X_end = X + dimension ;
00447   T acc = 0.0 ;
00448   while (X < X_end) {
00449     T x = *X++ ;
00450     T y = *Y++ ;
00451     if (x) acc += x * VL_XCAT(vl_log2_,SFX)(1 + y/x) ;
00452     if (y) acc += y * VL_XCAT(vl_log2_,SFX)(1 + x/y) ;
00453   }
00454   return (T)0.5 * acc ;
00455 }
00456 
00457 VL_EXPORT T
00458 VL_XCAT(_vl_distance_mahalanobis_sq_, SFX)
00459 (vl_size dimension, T const * X, T const * MU, T const * S)
00460 {
00461   T const * X_end = X + dimension ;
00462   T acc = 0.0 ;
00463   while (X < X_end) {
00464     T d = *X++ - *MU++ ;
00465     acc += d * d * (*S++) ;
00466   }
00467   return acc ;
00468 }
00469 
00470 /* ---------------------------------------------------------------- */
00471 
00472 VL_EXPORT COMPARISONFUNCTION_TYPE
00473 VL_XCAT(vl_get_vector_comparison_function_, SFX)(VlVectorComparisonType type)
00474 {
00475   COMPARISONFUNCTION_TYPE function = 0 ;
00476   switch (type) {
00477     case VlDistanceL2        : function = VL_XCAT(_vl_distance_l2_,             SFX) ; break ;
00478     case VlDistanceL1        : function = VL_XCAT(_vl_distance_l1_,             SFX) ; break ;
00479     case VlDistanceChi2      : function = VL_XCAT(_vl_distance_chi2_,           SFX) ; break ;
00480     case VlDistanceHellinger : function = VL_XCAT(_vl_distance_hellinger_,      SFX) ; break ;
00481     case VlDistanceJS        : function = VL_XCAT(_vl_distance_js_,             SFX) ; break ;
00482     case VlKernelL2          : function = VL_XCAT(_vl_kernel_l2_,               SFX) ; break ;
00483     case VlKernelL1          : function = VL_XCAT(_vl_kernel_l1_,               SFX) ; break ;
00484     case VlKernelChi2        : function = VL_XCAT(_vl_kernel_chi2_,             SFX) ; break ;
00485     case VlKernelHellinger   : function = VL_XCAT(_vl_kernel_hellinger_,        SFX) ; break ;
00486     case VlKernelJS          : function = VL_XCAT(_vl_kernel_js_,               SFX) ; break ;
00487     default: abort() ;
00488   }
00489 
00490 #ifndef VL_DISABLE_SSE2
00491   /* if a SSE2 implementation is available, use it */
00492   if (vl_cpu_has_sse2() && vl_get_simd_enabled()) {
00493     switch (type) {
00494       case VlDistanceL2    : function = VL_XCAT(_vl_distance_l2_sse2_,             SFX) ; break ;
00495       case VlDistanceL1    : function = VL_XCAT(_vl_distance_l1_sse2_,             SFX) ; break ;
00496       case VlDistanceChi2  : function = VL_XCAT(_vl_distance_chi2_sse2_,           SFX) ; break ;
00497       case VlKernelL2      : function = VL_XCAT(_vl_kernel_l2_sse2_,               SFX) ; break ;
00498       case VlKernelL1      : function = VL_XCAT(_vl_kernel_l1_sse2_,               SFX) ; break ;
00499       case VlKernelChi2    : function = VL_XCAT(_vl_kernel_chi2_sse2_,             SFX) ; break ;
00500       default: break ;
00501     }
00502   }
00503 #endif
00504 
00505 #ifndef VL_DISABLE_AVX
00506   /* if an AVX implementation is available, use it */
00507   if (vl_cpu_has_avx() && vl_get_simd_enabled()) {
00508     switch (type) {
00509       case VlDistanceL2    : function = VL_XCAT(_vl_distance_l2_avx_,             SFX) ; break ;
00510       default: break ;
00511     }
00512   }
00513 #endif
00514 
00515   return function ;
00516 }
00517 
00518 /* ---------------------------------------------------------------- */
00519 
00520 VL_EXPORT COMPARISONFUNCTION3_TYPE
00521 VL_XCAT(vl_get_vector_3_comparison_function_, SFX)(VlVectorComparisonType type)
00522 {
00523   COMPARISONFUNCTION3_TYPE function = 0 ;
00524   switch (type) {
00525     case VlDistanceMahalanobis : function = VL_XCAT(_vl_distance_mahalanobis_sq_, SFX) ; break ;
00526     default: abort() ;
00527   }
00528 
00529 #ifndef VL_DISABLE_SSE2
00530   /* if a SSE2 implementation is available, use it */
00531   if (vl_cpu_has_sse2() && vl_get_simd_enabled()) {
00532     switch (type) {
00533       case VlDistanceMahalanobis : function = VL_XCAT(_vl_distance_mahalanobis_sq_sse2_, SFX) ; break ;
00534       default: break ;
00535     }
00536   }
00537 #endif
00538 
00539 #ifndef VL_DISABLE_AVX
00540   /* if an AVX implementation is available, use it */
00541   if (vl_cpu_has_avx() && vl_get_simd_enabled()) {
00542     switch (type) {
00543       case VlDistanceMahalanobis : function = VL_XCAT(_vl_distance_mahalanobis_sq_avx_, SFX) ; break ;
00544       default: break ;
00545     }
00546   }
00547 #endif
00548 
00549   return function ;
00550 }
00551 
00552 /* ---------------------------------------------------------------- */
00553 
00554 VL_EXPORT void
00555 VL_XCAT(vl_eval_vector_comparison_on_all_pairs_, SFX)
00556 (T * result, vl_size dimension,
00557  T const * X, vl_size numDataX,
00558  T const * Y, vl_size numDataY,
00559  COMPARISONFUNCTION_TYPE function)
00560 {
00561   vl_uindex xi ;
00562   vl_uindex yi ;
00563 
00564   if (dimension == 0) return ;
00565   if (numDataX == 0) return ;
00566   assert (X) ;
00567 
00568   if (Y) {
00569     if (numDataY == 0) return ;
00570     for (yi = 0 ; yi < numDataY ; ++ yi) {
00571       for (xi = 0 ; xi < numDataX ; ++ xi) {
00572         *result++ = (*function)(dimension, X, Y) ;
00573         X += dimension ;
00574       }
00575       X -= dimension * numDataX ;
00576       Y += dimension ;
00577     }
00578   } else {
00579     T * resultTransp = result ;
00580     Y = X ;
00581     for (yi = 0 ; yi < numDataX ; ++ yi) {
00582       for (xi = 0 ; xi <= yi ; ++ xi) {
00583         T z = (*function)(dimension, X, Y) ;
00584         X += dimension ;
00585         *result       = z ;
00586         *resultTransp = z ;
00587         result        += 1 ;
00588         resultTransp  += numDataX ;
00589       }
00590       X -= dimension * (yi + 1) ;
00591       Y += dimension ;
00592       result       += numDataX - (yi + 1) ;
00593       resultTransp += 1        - (yi + 1) * numDataX ;
00594     }
00595   }
00596 }
00597 
00598 /* VL_MATHOP_INSTANTIATING */
00599 #endif
00600 
00601 
00602 /* ---------------------------------------------------------------- */
00603 /*                                               Numerical analysis */
00604 /* ---------------------------------------------------------------- */
00605 
00606 #ifndef VL_MATHOP_INSTANTIATING
00607 
00640 void
00641 vl_svd2 (double* S, double *U, double *V, double const *M)
00642 {
00643   double m11 = M[0] ;
00644   double m21 = M[1] ;
00645   double m12 = M[2] ;
00646   double m22 = M[3] ;
00647   double cu1 = m11 ;
00648   double su1 = m21 ;
00649   double norm = sqrt(cu1*cu1 + su1*su1) ;
00650   double cu2, su2, cv2, sv2 ;
00651   double f, g, h ;
00652   double smin, smax ;
00653   cu1 /= norm ;
00654   su1 /= norm ;
00655 
00656   f = cu1 * m11 + su1 * m21 ;
00657   g = cu1 * m12 + su1 * m22 ;
00658   h = - su1 * m12 + cu1 * m22 ;
00659 
00660   vl_lapack_dlasv2 (&smin, &smax,
00661                     &sv2, &cv2,
00662                     &su2, &cu2,
00663                     f, g, h) ;
00664 
00665   assert(S) ;
00666   S[0] = smax ;
00667   S[1] = 0 ;
00668   S[2] = 0 ;
00669   S[3] = smin ;
00670 
00671   if (U) {
00672     U[0] = cu2*cu1 - su2*su1 ;
00673     U[1] = su2*cu1 + cu2*su1 ;
00674     U[2] = - cu2*su1 - su2*cu1 ;
00675     U[3] = - su2*su1 + cu2*cu1 ;
00676   }
00677   if (V) {
00678     V[0] = cv2 ;
00679     V[1] = sv2 ;
00680     V[2] = - sv2 ;
00681     V[3] = cv2 ;
00682   }
00683 }
00684 
00709 #define isign(i) ((i)<0 ? (-1) : (+1))  /* integer sign function */
00710 #define sign(x) ((x)<0.0 ? (-1) : (+1)) /* double sign function */
00711 
00712 void
00713 vl_lapack_dlasv2 (double *smin,
00714                   double *smax,
00715                   double *sv,
00716                   double *cv,
00717                   double *su,
00718                   double *cu,
00719                   double f,
00720                   double g,
00721                   double h)
00722 {
00723   double svt, cvt, sut, cut; /* temporary sv, cv, su, and cu */
00724   double ft = f, gt = g, ht = h; /* temporary f, g, h */
00725   double fa = fabs(f), ga = fabs(g), ha = fabs(h); /* |f|, |g|, and |h| */
00726   int pmax = 1 ; /* pointer to max abs entry */
00727   int swap = 0 ; /* is swapped */
00728   int glarge = 0 ; /* is g very large */
00729   int tsign ; /* tmp sign */
00730   double fmh ; /* |f| -|h| */
00731   double d ; /* (|f| -|h|)/|f| */
00732   double dd ; /* d*d */
00733   double q ; /* g/f */
00734   double qq ; /* q*q */
00735   double s ; /* (|f| + |h|)/|f| */
00736   double ss ; /* s*s */
00737   double spq ; /* sqrt(ss + qq) */
00738   double dpq ; /* sqrt(dd + qq) */
00739   double a ; /* (spq + dpq)/2 */
00740   double tmp ; /* temporaries */
00741   double tt;
00742 
00743   /* make fa >= ha */
00744   if (fa < ha) {
00745     pmax = 3 ;
00746     tmp =ft ; ft = ht ; ht = tmp ; /* swap ft and ht */
00747     tmp =fa ; fa = ha ; ha = tmp ; /* swap fa and ha */
00748     swap = 1 ;
00749   }
00750 
00751   if (ga == 0.0) { /* diagonal */
00752     *smin = ha ;
00753     *smax = fa ;
00754     /* identity matrix */
00755     cut = 1.0 ; sut = 0.0 ;
00756     cvt = 1.0 ; svt = 0.0 ;
00757   }
00758   else { /* not diagonal */
00759     if (ga > fa) { /* g is the largest entry */
00760       pmax = 2 ;
00761       if ((fa / ga) < VL_EPSILON_D) { /* g is very large */
00762         glarge = 1 ;
00763         *smax = ga ; /* 1 ulp */
00764         if (ha > 1.0) {
00765           *smin = fa / (ga / ha) ; /* 2 ulps */
00766         } else {
00767           *smin = (fa / ga) * ha ; /* 2 ulps */
00768         }
00769         cut = 1.0 ; sut = ht / gt ;
00770         cvt = 1.0 ; svt = ft / gt ;
00771       }
00772     }
00773 
00774     if (glarge == 0) { /* normal case */
00775       fmh = fa - ha ; /* 1ulp */
00776       if (fmh == fa) {  /* cope with infinite f or h */
00777         d = 1.0 ;
00778       } else {
00779         d = fmh / fa ; /* note 0<=d<=1.0, 2 ulps */
00780       }
00781       q = gt / ft ; /* note |q|<1/EPS, 1 ulp */
00782       s = 2.0 - d ; /* note s>=1.0, 3 ulps */
00783       dd = d*d ;
00784       qq = q*q ;
00785       ss = s*s ;
00786       spq = sqrt(ss + qq) ; /* note 1<=spq<=1+1/EPS, 5 ulps */
00787       if (d == 0.0) {
00788         dpq = fabs(q) ; /* 0 ulp */
00789       } else {
00790         dpq = sqrt(dd + qq) ; /* note 0<=dpq<=1+1/EPS, 3.5 ulps */
00791       }
00792       a = 0.5 * (spq + dpq) ; /* note 1<=a<=1 + |q|, 6 ulps */
00793       *smin = ha / a; /* 7 ulps */
00794       *smax = fa * a; /* 7 ulps */
00795       if (qq==0.0) { /* qq underflow */
00796         if (d==0.0) {
00797           tmp = sign(ft)*2*sign(gt); /* 0ulp */
00798         }
00799         else {
00800           tmp = gt/(sign(ft)*fmh) + q/s; /* 6 ulps */
00801         }
00802       } else {
00803         tmp = (q/(spq + s) + q/(dpq + d))*(1.0 + a);  /* 17 ulps */
00804       }
00805       /* if qq */
00806       tt = sqrt(tmp*tmp + 4.0) ; /* 18.5 ulps */
00807       cvt = 2.0 / tt ; /* 19.5 ulps */
00808       svt = tmp / tt ; /* 36.5 ulps */
00809       cut = (cvt + svt*q) / a ; /* 46.5 ulps */
00810       sut = (ht / ft) * svt / a ; /* 45.5 ulps */
00811     } /* if g not large */
00812   } /* if ga */
00813   if (swap == 1) {
00814     *cu = svt ; *su = cvt ;
00815     *cv = sut ; *sv = cut ;
00816   } else {
00817     *cu = cut ; *su = sut ;
00818     *cv = cvt ; *sv = svt ;
00819   }
00820   /* correct the signs of smax and smin */
00821   if (pmax==1) { tsign = sign(*cv) * sign(*cu) * sign(f) ; }
00822   if (pmax==2) { tsign = sign(*sv) * sign(*cu) * sign(g) ; }
00823   if (pmax==3) { tsign = sign(*sv) * sign(*su) * sign(h) ; }
00824   *smax = isign(tsign) * (*smax);
00825   *smin = isign(tsign * sign(f) * sign(h)) * (*smin) ;
00826 }
00827 
00828 
00838 VL_EXPORT int
00839 vl_solve_linear_system_3 (double * x, double const * A, double const *b)
00840 {
00841   int err ;
00842   double M[3*4] ;
00843   M[0] = A[0] ;
00844   M[1] = A[1] ;
00845   M[2] = A[2] ;
00846   M[3] = A[3] ;
00847   M[4] = A[4] ;
00848   M[5] = A[5] ;
00849   M[6] = A[6] ;
00850   M[7] = A[7] ;
00851   M[8] = A[8] ;
00852   M[9] = b[0] ;
00853   M[10] = b[1] ;
00854   M[11] = b[2] ;
00855   err = vl_gaussian_elimination(M,3,4) ;
00856   x[0] = M[9] ;
00857   x[1] = M[10] ;
00858   x[2] = M[11] ;
00859   return err ;
00860 }
00861 
00871 VL_EXPORT int
00872 vl_solve_linear_system_2 (double * x, double const * A, double const *b)
00873 {
00874   int err ;
00875   double M[2*3] ;
00876   M[0] = A[0] ;
00877   M[1] = A[1] ;
00878   M[2] = A[2] ;
00879   M[3] = A[3] ;
00880   M[4] = b[0];
00881   M[5] = b[1] ;
00882   err = vl_gaussian_elimination(M,2,3) ;
00883   x[0] = M[4] ;
00884   x[1] = M[5] ;
00885   return err ;
00886 }
00887 
00905 VL_EXPORT vl_bool
00906 vl_gaussian_elimination (double * A, vl_size numRows, vl_size numColumns)
00907 {
00908   vl_index i, j, ii, jj ;
00909   assert(A) ;
00910   assert(numRows <= numColumns) ;
00911 
00912 #define Aat(i,j) A[(i) + (j)*numRows]
00913 
00914   /* Gauss elimination */
00915   for(j = 0 ; j < (signed)numRows ; ++j) {
00916     double maxa = 0 ;
00917     double maxabsa = 0 ;
00918     vl_index maxi = -1 ;
00919     double tmp ;
00920 
00921 #if 0
00922     {
00923       vl_index iii, jjj ;
00924       for (iii = 0 ; iii < 2 ; ++iii) {
00925         for (jjj = 0 ; jjj < 3 ; ++jjj) {
00926           VL_PRINTF("%5.2g ", Aat(iii,jjj)) ;
00927 
00928         }
00929         VL_PRINTF("\n") ;
00930       }
00931       VL_PRINTF("\n") ;
00932     }
00933 #endif
00934 
00935     /* look for the maximally stable pivot */
00936     for (i = j ; i < (signed)numRows ; ++i) {
00937       double a = Aat(i,j) ;
00938       double absa = vl_abs_d (a) ;
00939       if (absa > maxabsa) {
00940         maxa = a ;
00941         maxabsa = absa ;
00942         maxi = i ;
00943       }
00944     }
00945     i = maxi ;
00946 
00947     /* if singular give up */
00948     if (maxabsa < 1e-10) return VL_ERR_OVERFLOW ;
00949 
00950     /* swap j-th row with i-th row and normalize j-th row */
00951     for(jj = j ; jj < (signed)numColumns ; ++jj) {
00952       tmp = Aat(i,jj) ; Aat(i,jj) = Aat(j,jj) ; Aat(j,jj) = tmp ;
00953       Aat(j,jj) /= maxa ;
00954     }
00955 
00956 #if 0
00957     {
00958       vl_index iii, jjj ;
00959       VL_PRINTF("after swap %d %d\n", j, i);
00960       for (iii = 0 ; iii < 2 ; ++iii) {
00961         for (jjj = 0 ; jjj < 3 ; ++jjj) {
00962           VL_PRINTF("%5.2g ", Aat(iii,jjj)) ;
00963 
00964         }
00965         VL_PRINTF("\n") ;
00966       }
00967       VL_PRINTF("\n") ;
00968     }
00969 #endif
00970 
00971     /* elimination */
00972     for (ii = j+1 ; ii < (signed)numRows ; ++ii) {
00973       double x = Aat(ii,j) ;
00974       for (jj = j ; jj < (signed)numColumns ; ++jj) {
00975         Aat(ii,jj) -= x * Aat(j,jj) ;
00976       }
00977     }
00978 
00979 #if 0
00980     {
00981       VL_PRINTF("after elimination\n");
00982 
00983       vl_index iii, jjj ;
00984       for (iii = 0 ; iii < 2 ; ++iii) {
00985         for (jjj = 0 ; jjj < 3 ; ++jjj) {
00986           VL_PRINTF("%5.2g ", Aat(iii,jjj)) ;
00987 
00988         }
00989         VL_PRINTF("\n") ;
00990       }
00991       VL_PRINTF("\n") ;
00992     }
00993 #endif
00994 
00995   }
00996 
00997   /* backward substitution */
00998   for (i = numRows - 1 ; i > 0 ; --i) {
00999     /* substitute in all rows above */
01000     for (ii = i - 1 ; ii >= 0 ; --ii) {
01001       double x = Aat(ii,i) ;
01002       /* j = numRows */
01003       for (j = numRows ; j < (signed)numColumns ; ++j) {
01004         Aat(ii,j) -= x * Aat(i,j) ;
01005       }
01006     }
01007   }
01008 
01009 #if 0
01010   {
01011     VL_PRINTF("after substitution\n");
01012 
01013     vl_index iii, jjj ;
01014     for (iii = 0 ; iii < 2 ; ++iii) {
01015       for (jjj = 0 ; jjj < 3 ; ++jjj) {
01016         VL_PRINTF("%5.2g ", Aat(iii,jjj)) ;
01017 
01018       }
01019       VL_PRINTF("\n") ;
01020     }
01021     VL_PRINTF("\n") ;
01022   }
01023 #endif
01024 
01025 
01026   return VL_ERR_OK ;
01027 }
01028 
01029 /* VL_MATHOP_INSTANTIATING */
01030 #endif
01031 
01032 #undef VL_MATHOP_INSTANTIATING


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51