Add thread-safe logging functions
[openmx:openmx.git] / src / omxSadmvnWrapper.cpp
1 /*
2  *  Copyright 2007-2013 The OpenMx Project
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 #include <R.h>
18 #include <Rinternals.h>
19 #include <Rdefines.h>
20 #include <R_ext/Rdynload.h>
21 #include <R_ext/BLAS.h>
22 #include <R_ext/Lapack.h>
23 #include "omxDefines.h"
24 #include "omxAlgebraFunctions.h"
25 #include "omxSymbolTable.h"
26 #include "omxData.h"
27 #include "omxFIMLFitFunction.h"
28 #include "omxOpenmpWrap.h"
29 #include "omxSadmvnWrapper.h"
30
31 void omxSadmvnWrapper(omxFitFunction *oo, omxMatrix *cov, omxMatrix *ordCov, 
32         double *corList, double *lThresh, double *uThresh, int *Infin, double *likelihood, int *inform) {
33     // SADMVN calls Alan Genz's sadmvn.f--see appropriate file for licensing info.
34         // TODO: Check with Genz: should we be using sadmvn or sadmvn?
35         // Parameters are:
36         //      N               int                     # of vars
37         //      Lower   double*         Array of lower bounds
38         //      Upper   double*         Array of upper bounds
39         //      Infin   int*            Array of flags: 0 = (-Inf, upper] 1 = [lower, Inf), 2 = [lower, upper]
40         //      Correl  double*         Array of correlation coeffs: in row-major lower triangular order
41         //      MaxPts  int                     Maximum # of function values (use 1000*N or 1000*N*N)
42         //      Abseps  double          Absolute error tolerance.  Yick.
43         //      Releps  double          Relative error tolerance.  Use EPSILON.
44         //      Error   &double         On return: absolute real error, 99% confidence
45         //      Value   &double         On return: evaluated value
46         //      Inform  &int            On return: 0 = OK; 1 = Rerun, increase MaxPts; 2 = Bad input
47         // TODO: Separate block diagonal covariance matrices into pieces for integration separately
48         double Error;
49         double absEps = 1e-3;
50         double relEps = 0;
51         int MaxPts = 100000*cov->rows;
52         int numVars = ordCov->rows;
53         int fortranThreadId = omx_absolute_thread_num() + 1;
54         /* FOR DEBUGGING PURPOSES */
55     /*  numVars = 2;
56         lThresh[0] = -2;
57         uThresh[0] = -1.636364;
58         Infin[0] = 2;
59         lThresh[1] = 0;
60         uThresh[1] = 0;
61         Infin[1] = 0;
62         smallCor[0] = 1.0; smallCor[1] = 0; smallCor[2] = 1.0; */
63         F77_CALL(sadmvn)(&numVars, lThresh, uThresh, Infin, corList, &MaxPts, 
64                 &absEps, &relEps, &Error, likelihood, inform, &fortranThreadId);
65
66         if(OMX_DEBUG && !oo->matrix->currentState->currentRow) {
67                 char infinCodes[3][20];
68                 strcpy(infinCodes[0], "(-INF, upper]");
69                 strcpy(infinCodes[1], "[lower, INF)");
70                 strcpy(infinCodes[2], "[lower, upper]");
71                 mxLog("Input to sadmvn is (%d rows):", numVars); //:::DEBUG:::
72                 omxPrint(ordCov, "Ordinal Covariance Matrix"); //:::DEBUG:::
73                 for(int i = 0; i < numVars; i++) {
74                         mxLog("Row %d: %f, %f, %d(%s)", i, lThresh[i], uThresh[i], Infin[i], infinCodes[Infin[i]]);
75                 }
76
77                 mxLog("Cor: (Lower %d x %d):", cov->rows, cov->cols); //:::DEBUG:::
78                 for(int i = 0; i < cov->rows*(cov->rows-1)/2; i++) {
79                         // mxLog("Row %d of Cor: ", i);
80                         // for(int j = 0; j < i; j++)
81                         mxLog(" %f", corList[i]); // (i*(i-1)/2) + j]);
82                         // mxLog("");
83                 }
84                 mxLog("");
85         }
86
87         if(OMX_DEBUG) {
88                 mxLog("Output of sadmvn is %f, %f, %d.", Error, *likelihood, *inform); 
89         }
90