KerMor  0.9
Model order reduction for nonlinear dynamical systems and nonlinear approximation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
evaluateMex.c
Go to the documentation of this file.
1 #include <mex.h>
2 #include <math.h>
3 #include <omp.h>
4 
5 /* Implements the sum(x.^2,1) matlab command for a matrix x */
6 void sumsq(double* xsq, double* x, int n, int m) {
7  int i, j, *v, vfirst;
8 
9 #ifdef DEBUG
10  char temp[100];
11 #endif
12 
13  #pragma omp parallel for shared(xsq,x,n,m) private(i,j)
14  for (j=0;j<m;j++) {
15  xsq[j] = 0;
16 /*
17  vfirst = x[j*n]; v = &vfirst;
18 */
19  for (i=0;i<n;i++) {
20  xsq[j] += x[j*n+i]*x[j*n+i];
21 /*
22  xsq[j] += v[i]*v[i];
23 */
24 #ifdef DEBUG
25  sprintf(temp, "j(m)=%d(%d), i(n)=%d(%d), x=%.12f\n", j, m, i, n, x[j*n+i]);
26  mexPrintf(temp);
27 #endif
28  }
29  }
30 }
31 
32 void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
33  double *x, *y, *res, gamma, hlp;
34 
35  int i, j, k, l, m, n;
36 
37 #ifdef DEBUG
38  char temp[100];
39 #endif
40 
41  /* const mxArray *net; */
42 
43  /*
44  * if (nrhs != 3)
45  * {
46  * mexErrMsgTxt("Wrong number input arguments.");
47  * }
48  * else if (nlhs > 1)
49  * {
50  * mexErrMsgTxt("Too many output arguments.");
51  * }*/
52 
53  /*
54  * if (!mxIsDouble(prhs[1]) || mxIsComplex(prhs[1]))
55  * {
56  * mexErrMsgTxt("x1 must be a double matrix.");
57  * }
58  */
59  n = mxGetM(prhs[1]);
60  m = mxGetN(prhs[1]);
61  x = mxGetPr(prhs[1]);
62 
63  /*
64  * if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]))
65  * {
66  * mexErrMsgTxt("x2 must be a double matrix.");
67  * }
68  */
69 
70  double xsq[m];
71  sumsq(xsq, x, n, m);
72 
73  /* Get gamma value */
74  gamma = mxGetScalar(mxGetProperty(prhs[0], 0, "Gamma"));
75 
76 #ifdef DEBUG
77  sprintf(temp, "Gamma=%.12f\n", gamma);
78  mexPrintf(temp);
79 #endif
80 
81  /* One argument case (symmetric matrix) */
82  if (nrhs == 2) {
83  /* Output init */
84  plhs[0] = mxCreateDoubleMatrix(m, m, mxREAL);
85  res = mxGetPr(plhs[0]);
86 
87 #ifdef DEBUG
88  sprintf(temp, "Call with one parameter!\n");
89  mexPrintf(temp);
90 #endif
91  /* Diagonal with ones */
92  for(i=0;i<m;i++) {
93  res[i*m+i] = 1;
94  }
95 
96  /* Only compute lower left triangular & copy values */
97  #pragma omp parallel for shared(res,xsq,x,n,m) private(hlp,i,j,l)
98  for (i = 1; i < m; i++) {
99  for (j = 0; j < i; j++) {
100  hlp=0;
101  for (l = 0; l < n; l++) {
102 #ifdef DEBUG
103  sprintf(temp, "ScaP i=%d, j=%d, l=%d, x=%.12f, y=%.12f\n", i, j, l, x[i*n+l], y[j*n+l]);
104  mexPrintf(temp);
105 #endif
106  hlp += x[i*n+l]*x[j*n+l];
107  }
108 #ifdef DEBUG
109  sprintf(temp, "xsq[i]=%.12f, xsq[j]=%.12f, x*y=%.12f\n", xsq[i], xsq[j], hlp);
110  mexPrintf(temp);
111 #endif
112  res[i+j*m] = exp(-(xsq[i]+xsq[j]-2*hlp)/gamma);
113  /* Copy lower left triangular to upper right */
114  res[j+i*m] = res[i+j*m];
115  }
116  }
117 
118  /* Two argument case */
119  } else {
120 
121 
122 #ifdef DEBUG
123  sprintf(temp, "Call with two parameters!\n");
124  mexPrintf(temp);
125 #endif
126  if (n != mxGetM(prhs[2]))
127  mexErrMsgTxt("GaussKernel.evaluate (mex): Array dimensions must match");
128 
129  k = mxGetN(prhs[2]);
130  y = mxGetPr(prhs[2]);
131 
132  plhs[0] = mxCreateDoubleMatrix(m, k, mxREAL);
133  res = mxGetPr(plhs[0]);
134 
135  double ysq[k];
136  sumsq(ysq, y, n, k);
137  /* Check for the correct loop to split up, depending on whether more columns or
138  rows are given */
139  if (m > k) {
140  #pragma omp parallel for shared(res,xsq,ysq,x,y,n,m,k) private(hlp,i,j,l)
141  for (i = 0; i < m; i++) {
142  for (j = 0; j < k; j++) {
143  hlp=0;
144  for (l = 0; l < n; l++) {
145 #ifdef DEBUG
146  sprintf(temp, "ScaP i=%d, j=%d, l=%d, x=%.12f, y=%.12f\n", i, j, l, x[i*n+l], y[j*n+l]);
147  mexPrintf(temp);
148 #endif
149  hlp += x[i*n+l]*y[j*n+l];
150  }
151 #ifdef DEBUG
152  sprintf(temp, "xsq=%.12f, ysq=%.12f, x*y=%.12f\n", xsq[i], ysq[j], hlp);
153  mexPrintf(temp);
154 #endif
155  res[i+j*m] = exp(-(xsq[i]+ysq[j]-2*hlp)/gamma);
156  }
157  }
158  } else {
159  #pragma omp parallel for shared(res,xsq,ysq,x,y,n,m,k) private(hlp,i,j,l)
160  for (j = 0; j < k; j++) {
161  for (i = 0; i < m; i++) {
162  hlp=0;
163  for (l = 0; l < n; l++) {
164 #ifdef DEBUG
165  sprintf(temp, "ScaP i=%d, j=%d, l=%d, x=%.12f, y=%.12f\n", i, j, l, x[i*n+l], y[j*n+l]);
166  mexPrintf(temp);
167 #endif
168  hlp += x[i*n+l]*y[j*n+l];
169  }
170 #ifdef DEBUG
171  sprintf(temp, "xsq=%.12f, ysq=%.12f, x*y=%.12f\n", xsq[i], ysq[j], hlp);
172  mexPrintf(temp);
173 #endif
174  res[i+j*m] = exp(-(xsq[i]+ysq[j]-2*hlp)/gamma);
175  }
176  }
177  }
178  }
179 }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Definition: evaluateMex.c:32
void sumsq(double *xsq, double *x, int n, int m)
Definition: evaluateMex.c:6