LCOV - code coverage report
Current view: top level - src - roc.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 60 0.0 %
Date: 2020-12-14 08:13:14 Functions: 0 1 0.0 %

          Line data    Source code
       1             : #include <assert.h>
       2             : #include <float.h>
       3             : #include <stdio.h>
       4             : #include <stdlib.h>
       5             : #include <tgmath.h>
       6             : 
       7             : #include "qrfactorization.h"
       8             : 
       9             : #define map(i, j) ((j)-1) * lda + ((i)-1)
      10             : #define a(i, j) a[ map(i, j) ]
      11             : #define map1(i) (i) - 1
      12             : #define x(i) x[ map1(i) ]
      13             : #define y(i) y[ map1(i) ]
      14             : #define ipiv(i) ipiv[ map1(i) ]
      15             : #define tc(i) tc[ map1(i) ]
      16             : 
      17             : //  error code 1 if less than 10 coefficients to estimate Rc
      18             : 
      19           0 : int roc(int num_tc, double *tc, double scale, int kstart, double *rc,
      20             :         double *slope, double *intercept)
      21             : {
      22           0 :   if (num_tc - kstart < 11)
      23             :   {
      24           0 :     printf(
      25             :         "Message from ROC: Need at least 10 Taylor coefficients to estimate "
      26             :         "Rc\n");
      27           0 :     return 1;
      28             :   }
      29             : 
      30           0 :   int m = num_tc - kstart + 1;
      31           0 :   int lda = m, n = 2, min_m_n = 0;
      32           0 :   int res = 0, ier = 0;
      33           0 :   double *a = NULL;
      34           0 :   int *ipiv = NULL;
      35           0 :   double *tau = NULL;
      36           0 :   double *wrk = NULL;
      37           0 :   double *x = NULL;
      38           0 :   double *y = NULL;
      39           0 :   double safmin = DBL_MIN;
      40             : 
      41           0 :   min_m_n = (m < n) ? m : n;
      42             : 
      43           0 :   a = (double *)calloc((size_t)(lda * n), (size_t)sizeof(double));
      44           0 :   if (a == NULL)
      45             :   {
      46           0 :     printf("Failed to allocate matrix A memory!\n");
      47           0 :     assert(a);
      48             :   }
      49             : 
      50           0 :   tau = (double *)calloc((size_t)min_m_n, (size_t)sizeof(double));
      51           0 :   if (tau == NULL)
      52             :   {
      53           0 :     printf("Failed to allocate tau memory!\n");
      54           0 :     assert(tau);
      55             :   }
      56             : 
      57           0 :   wrk = (double *)calloc((size_t)n, (size_t)sizeof(double));
      58           0 :   if (wrk == NULL)
      59             :   {
      60           0 :     printf("Failed to allocate wrk memory!\n");
      61           0 :     assert(wrk);
      62             :   }
      63             : 
      64           0 :   ipiv = (int *)calloc((size_t)n, (size_t)sizeof(int));
      65           0 :   if (ipiv == NULL)
      66             :   {
      67           0 :     printf("Failed to allocate ipiv memory!\n");
      68           0 :     assert(ipiv);
      69             :   }
      70             : 
      71           0 :   x = (double *)calloc((size_t)n, (size_t)sizeof(double));
      72           0 :   if (x == NULL)
      73             :   {
      74           0 :     printf("Failed to allocate space for result x!\n");
      75           0 :     assert(x);
      76             :   }
      77             : 
      78           0 :   y = (double *)calloc((size_t)m, (size_t)sizeof(double));
      79           0 :   if (y == NULL)
      80             :   {
      81           0 :     printf("Failed to allocate space for result y!\n");
      82           0 :     assert(y);
      83             :   }
      84             : 
      85             :   // Construct the least squares linear system
      86             :   //
      87             :   // We want to fit the tail of the Taylor series, ignore the first kstart terms
      88             :   // of the TCs.
      89           0 :   for (int k = kstart; k <= num_tc; k++)
      90             :   {
      91           0 :     int row = k - kstart + 1;
      92           0 :     a(row, 1) = 1.0;
      93           0 :     a(row, 2) = (double)k;
      94           0 :     y(row) = log10(fabs(tc(k)));
      95             :   }
      96             : 
      97             :   // Find the QRFactorization of the least squares linear system
      98           0 :   res = qrf(m, n, a, lda, ipiv, tau, wrk, safmin, &ier);
      99           0 :   if (res != 0 || ier != 0)
     100             :   {
     101           0 :     printf("Error QR factoring A with res[%d]!=0 or ier[%d]!=0\n", res, ier);
     102             :   }
     103             : 
     104             :   // Find the least squares solution of the linear system via the
     105             :   // QRFactorization
     106             :   //
     107             :   // Solve on the first (two) n rows of R as in
     108             :   // transpose(Q)*b=transpose(Q)*A*E*E*x=transpose(Q)*Q*R*E*x=R*E*x
     109           0 :   res = qrs(m, n, a, lda, tau, y, x, &ier);
     110           0 :   if (res != 0 || ier != 0)
     111             :   {
     112           0 :     printf(
     113             :         "Error finding the Least Squares Solution with res[%d]!=0 or "
     114             :         "ier[%d]!=0\n",
     115             :         res, ier);
     116             :   }
     117             : 
     118             :   // If Taylor coefficients TC(i) are unscaled, then the scaled TCs are
     119             :   // T(i) = (1/scale)^i TC(i).
     120             :   //
     121             :   // Multiply Rc by scale to get Rc when computing with scaled TCs.
     122             :   //
     123             :   // See this from ratio test as Rc is 1/L where
     124             :   //
     125             :   //   L = (1/scale)*limit of abs(TC(i+1)/TC(i)) = limit of abs(T(i+1)/T(i)).
     126             :   //
     127             :   // To justify the formula for Rc, consider the problem of fitting m and b
     128             :   //
     129             :   // log10(abs(T(i))) = y(i) = b + m*i = [1 i](b,m)
     130             :   //
     131             :   // by linear least squares. Then
     132             :   //
     133             :   // Log10(L) = Log10(abs(T(i+1))/abs(T(i))) =
     134             :   // Log10(abs(T(i+1)))-Log10(abs(T(i)))
     135             :   //          = m*(i+1)+b - (m*i+b) = m
     136             :   //
     137             :   // It follows that
     138             :   //
     139             :   // rc = 1/L = scale/pow(10, m).
     140           0 :   *rc = scale / pow(10, x(ipiv(2)));
     141           0 :   *intercept = x(ipiv(1));
     142           0 :   *slope = x(ipiv(2));
     143             : 
     144           0 :   free(y);
     145           0 :   free(x);
     146           0 :   free(ipiv);
     147           0 :   free(wrk);
     148           0 :   free(tau);
     149           0 :   free(a);
     150             : 
     151           0 :   return 0;
     152             : }

Generated by: LCOV version 1.14