Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/03/17 20:28:37 (6 years ago)
Author:
gkronber
Message:

#2789 created x64 build of CUBGCV algorithm, fixed some bugs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/MathNetNumerics-Exploration-2789/HeuristicLab.Algorithms.DataAnalysis.Experimental/CubicSplineGCV.cs

    r15443 r15449  
    11using System;
    22using System.Collections.Generic;
     3using System.Diagnostics;
    34using System.Linq;
    45using System.Runtime.InteropServices;
    56using System.Text;
    67using System.Threading.Tasks;
     8using HeuristicLab.Problems.DataAnalysis;
    79
    810namespace HeuristicLab.Algorithms.DataAnalysis.Experimental {
     
    105107    //                           IER = 133, JOB IS NOT 0 OR 1.
    106108
    107     // TODO: Build x64 version of the library using mingw
    108     // TODO: statically link all required libraries (libgcc_s_dw2-1.dll is still required)
    109     // To build the fortran library use:
    110     // > gfortran -static -Lc:/mingw/bin/libgcc_s_dw2-1.dll -m32 642.f -shared -o 642_x86.dll
    111     // this means that libgcc_s_dw2-1 is statically linked, i386 code is produced and a shared library is produced
     109    // To build the fortran library (x64) use:
     110    // > gfortran -m64 642.f -shared -o 642_x64.dll  or
     111    // > ifort /dll /Qm64 642.f /Fe642_x64.dll
     112    // check dumpbin /EXPORTS 642_x64.dll
     113    // and   dumpbin /IMPORTS 642_x64.dll
    112114    [DllImport("642_x64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "cubgcv")]
    113115    public static extern void cubgcv_x64(
    114       double[] x, double[] f, double[] df, ref int n, double[] y, double[,] c, ref int ic, ref double var, ref int job, double[] se, double[,] wk);
    115 
    116     // CUBGCV(X, F, DF, N, Y, C, IC, VAR, JOB, SE, WK, IER)
     116      double[] x,
     117      double[] f,
     118      double[] df,
     119      ref int n,
     120      [Out] double[] y,
     121      [Out] double[,] c,
     122      ref int ic,
     123      ref double var,
     124      ref int job,
     125      [Out] double[] se,
     126      double[,] wk,
     127      ref int ier);
     128
     129    // To build the fortran library (x86) use:
     130    // > gfortran -static -Lc:/mingw/bin/libgcc_s_dw2-1.dll -m32 642.f -shared -o 642_x86.dll
    117131    [DllImport("642_x86.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "cubgcv")]
    118132    public static extern void cubgcv_x86(
    119       double[] x, 
    120       double[] f, 
    121       double[] df, 
    122       ref int n,
    123       double[] y, 
    124       double[,] c, 
    125       ref int ic,
    126       ref double var, 
    127       ref int job,
    128       double[] se, 
     133      double[] x,
     134      double[] f,
     135      double[] df,
     136      ref Int32 n,
     137      double[] y,
     138      double[,] c,
     139      ref Int32 ic,
     140      ref double var,
     141      ref Int32 job,
     142      double[] se,
    129143      double[,] wk,
    130       ref int ier);
     144      ref Int32 ier);
     145
     146
     147    public class CubGcvReport {
     148      //
     149      //   
     150      //
     151      //
     152      //   IF WK(1)=0 (RHO=0) AN INTERPOLATING NATURAL CUBIC
     153      //   SPLINE HAS BEEN CALCULATED.
     154      //   IF WK(1)=1 (RHO=INFINITE) A LEAST SQUARES
     155      //   REGRESSION LINE HAS BEEN CALCULATED.
     156      //
     157      public double smoothingParameter;
     158      //   WK(2) IS AN ESTIMATE OF THE NUMBER OF DEGREES OF
     159      //   FREEDOM OF THE RESIDUAL WHICH REDUCES TO THE
     160      //   USUAL VALUE OF N-2 WHEN A LEAST SQUARES REGRESSION
     161      //   LINE IS CALCULATED.
     162      public double estimatedRSSDegreesOfFreedom;
     163      //   WK(3),WK(4),WK(5) ARE CALCULATED WITH THE DF(I)
     164      //   SCALED TO HAVE MEAN SQUARE VALUE 1.  THE
     165      //   UNSCALED VALUES OF WK(3),WK(4),WK(5) MAY BE
     166      //   CALCULATED BY DIVIDING BY WK(7).
     167      public double generalizedCrossValidation;
     168      public double meanSquareResiudal;
     169      public double estimatedTrueMeanSquaredErrorAtDataPoints;
     170
     171      //   WK(6) COINCIDES WITH THE OUTPUT VALUE OF VAR IF
     172      //   VAR IS NEGATIVE ON INPUT.  IT IS CALCULATED WITH
     173      //   THE UNSCALED VALUES OF THE DF(I) TO FACILITATE
     174      //   COMPARISONS WITH A PRIORI VARIANCE ESTIMATES.
     175      public double estimatedErrorVariance;
     176      public double meanSquareOfDf;
     177      public double[] se;
     178    }
     179    public static ReinschSmoothingSplineModel CalculateCubicSpline(double[] x, double[] y,
     180      string targetVariable, string[] inputVars,
     181      out CubGcvReport report) {
     182      var w = Enumerable.Repeat(1.0, x.Length).ToArray();
     183      double[] x2, y2, w2;
     184      Splines.SortAndBin(x, y, w, out x2, out y2, out w2);
     185      // TODO: use weights correctly
     186
     187      int n = x2.Length;
     188      double[] df = Enumerable.Repeat(1.0, n).ToArray();   // set each df if actual standard deviation of data points is not known
     189      double[,] c = new double[3, n - 1];
     190      double var = -99.0;
     191      double[] se = new double[n]; // standard errors in points
     192      double[,] wk = new double[7, (n + 2)]; // work array;
     193      double[] y_smoothed = new double[n];
     194      int job = 1; // calc estimates of standard errors in points
     195      int ic = n - 1;
     196      int ier = -99;
     197      if (Environment.Is64BitProcess) {
     198        CubicSplineGCV.cubgcv_x64(x2, y2, df, ref n, y_smoothed,
     199          c, ref ic, ref var, ref job, se, wk, ref ier);
     200      } else {
     201        CubicSplineGCV.cubgcv_x86(x2, y2, df, ref n, y_smoothed,
     202          c, ref ic, ref var, ref job, se, wk, ref ier);
     203
     204
     205      }
     206
     207      /*
     208       *                  IER    - ERROR PARAMETER. (OUTPUT)
     209       *                           TERMINAL ERROR
     210       *                             IER = 129, IC IS LESS THAN N-1.
     211       *                             IER = 130, N IS LESS THAN 3.
     212       *                             IER = 131, INPUT ABSCISSAE ARE NOT
     213       *                               ORDERED SO THAT X(I).LT.X(I+1).
     214       *                             IER = 132, DF(I) IS NOT POSITIVE FOR SOME I.
     215       *                             IER = 133, JOB IS NOT 0 OR 1.
     216       *
     217       */
     218
     219      if (ier == 131) {
     220        throw new ArgumentException("x is not ordered");
     221      } else if (ier != 0) throw new ArgumentException("Error in CUBGCV " + ier);
     222
     223      //                           OF THE SPLINE APPROXIMATION AT T IS
     224      //                           S(T)=((C(I,3)*D+C(I,2))*D+C(I,1))*D+Y(I)
     225      //                           WHERE X(I).LE.T.LT.X(I+1) AND
     226      //                           D = T-X(I).
     227
     228      //                           WK(1) = SMOOTHING PARAMETER (= RHO/(RHO + 1))
     229      //                           WK(2) = ESTIMATE OF THE NUMBER OF DEGREES OF
     230      //                                   FREEDOM OF THE RESIDUAL SUM OF SQUARES
     231      //                           WK(3) = GENERALIZED CROSS VALIDATION
     232      //                           WK(4) = MEAN SQUARE RESIDUAL
     233      //                           WK(5) = ESTIMATE OF THE TRUE MEAN SQUARE ERROR
     234      //                                   AT THE DATA POINTS
     235      //                           WK(6) = ESTIMATE OF THE ERROR VARIANCE
     236      //                           WK(7) = MEAN SQUARE VALUE OF THE DF(I)
     237      report = new CubGcvReport();
     238      report.smoothingParameter = wk[0, 0];
     239      report.estimatedRSSDegreesOfFreedom = wk[0, 1];
     240      report.generalizedCrossValidation = wk[0, 2];
     241      report.meanSquareResiudal = wk[0, 3];
     242      report.estimatedTrueMeanSquaredErrorAtDataPoints = wk[0, 4];
     243      report.estimatedErrorVariance = wk[0, 5];
     244      report.meanSquareOfDf = wk[0, 6];
     245      report.se = se;
     246      Debug.Assert(var == report.estimatedErrorVariance);
     247
     248
     249
     250      double[] dArr = new double[n];
     251      double[] cArr = new double[n];
     252      double[] bArr = new double[n];
     253
     254      for (int i = 0; i < n - 1; i++) {
     255        bArr[i] = c[0, i];
     256        cArr[i] = c[1, i];
     257        dArr[i] = c[2, i];
     258      }
     259
     260      // extrapolate linearly for xx > x[n]
     261      bArr[n - 1] = bArr[n - 2];
     262      // extrapolate linearly for xx < x[1]
     263      dArr[0] = 0;
     264
     265      return new ReinschSmoothingSplineModel(
     266        new MyArray<double>(1, y_smoothed),
     267        new MyArray<double>(1, bArr),
     268        new MyArray<double>(1, cArr),
     269        new MyArray<double>(1, dArr),
     270        new MyArray<double>(1, x2),
     271        targetVariable, inputVars);
     272
     273
     274    }
     275
    131276  }
    132 
    133277}
Note: See TracChangeset for help on using the changeset viewer.