00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <mexutils.h>
00020
00021 #include <vl/generic.h>
00022
00023 #include <math.h>
00024 #include <stdlib.h>
00025
00028 #define greater(a,b) (a) > (b)
00029 #define getM(arg) mxGetM(in[arg])
00030 #define getN(arg) mxGetN(in[arg])
00031 #define getPr(arg) mxGetPr(in[arg])
00032
00033 VL_INLINE int
00034 findNeighbor(double x, const double* X, int K) {
00035 int i = 0 ;
00036 int j = K - 1 ;
00037 int pivot = 0 ;
00038 double y = 0 ;
00039 if(x < X[i]) return i-1 ;
00040 if(x >= X[j]) return j ;
00041
00042 while(i < j - 1) {
00043 pivot = (i+j) >> 1 ;
00044 y = X[pivot] ;
00045
00046 if(x < y) {
00047 j = pivot ;
00048 } else {
00049 i = pivot ;
00050 }
00051 }
00052 return i ;
00053 }
00054
00055 void
00056 mexFunction(int nout, mxArray *out[],
00057 int nin, const mxArray *in[])
00058 {
00059 enum { X=0,Y,I,iwXp,iwYp } ;
00060 enum { wI=0, wIx, wIy } ;
00061
00062 int M, N, Mp, Np, ip, jp ;
00063 double
00064 *X_pt,
00065 *Y_pt,
00066 *I_pt,
00067 *iwXp_pt,
00068 *iwYp_pt,
00069 *wI_pt,
00070 *wIx_pt = 0,
00071 *wIy_pt = 0 ;
00072
00073 double Xmin, Xmax, Ymin, Ymax ;
00074 const double NaN = mxGetNaN() ;
00075
00076
00077
00078
00079 if (nin < 5) {
00080 vlmxError (vlmxErrNotEnoughInputArguments, NULL) ;
00081 }
00082 if (nin > 5) {
00083 vlmxError (vlmxErrTooManyOutputArguments, NULL) ;
00084 }
00085 if (nout > 3) {
00086 vlmxError (vlmxErrTooManyOutputArguments, NULL) ;
00087 }
00088
00089 if (! vlmxIsPlainMatrix(in[I], -1, -1)) {
00090 vlmxError (vlmxErrInvalidArgument, "I is not a plain matrix.") ;
00091 }
00092
00093 if (! vlmxIsPlainMatrix(in[iwXp], -1, -1)) {
00094 vlmxError(vlmxErrInvalidArgument, "iwXp is not a plain matrix.") ;
00095 }
00096
00097 M = getM(I) ;
00098 N = getN(I) ;
00099 Mp = getM(iwXp) ;
00100 Np = getN(iwXp) ;
00101
00102 if(!vlmxIsPlainMatrix(in[iwYp], Mp, Np)) {
00103 vlmxError(vlmxErrInvalidArgument,
00104 "iwXp is not a plain matrix of the same idmension of iwYp.") ;
00105 }
00106
00107 if(!vlmxIsPlainVector(in[X],N) || !vlmxIsPlainVector(in[Y],M)) {
00108 vlmxError(vlmxErrInvalidArgument,
00109 "X and Y are not plain vectors with a length equal to the"
00110 " number of columns and rows of I.") ;
00111 }
00112
00113 X_pt = getPr(X);
00114 Y_pt = getPr(Y) ;
00115 I_pt = getPr(I) ;
00116 iwXp_pt = getPr(iwXp) ;
00117 iwYp_pt = getPr(iwYp) ;
00118
00119
00120 out[wI] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ;
00121 wI_pt = mxGetPr(out[wI]) ;
00122
00123 if (nout > 1) {
00124 out[wIx] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ;
00125 out[wIy] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ;
00126 wIx_pt = mxGetPr (out[wIx]) ;
00127 wIy_pt = mxGetPr (out[wIy]) ;
00128 }
00129
00130
00131
00132
00133 Xmin = X_pt [0] ;
00134 Xmax = X_pt [N - 1] ;
00135 Ymin = Y_pt [0] ;
00136 Ymax = Y_pt [M - 1] ;
00137
00138 if (nout <= 1) {
00139
00140
00141 for(jp = 0 ; jp < Np ; ++jp) {
00142 for(ip = 0 ; ip < Mp ; ++ip) {
00143
00144 double x = *iwXp_pt++ ;
00145 double y = *iwYp_pt++ ;
00146 double z = NaN ;
00147
00148
00149
00150 if(x >= Xmin && x <= Xmax &&
00151 y >= Ymin && y <= Ymax) {
00152 int j = findNeighbor(x, X_pt, N) ;
00153 int i = findNeighbor(y, Y_pt, M) ;
00154 double* pt = I_pt + j*M + i ;
00155
00156
00157 double x0 = X_pt[j] ;
00158 double x1 = (j < N-1) ? X_pt[j+1] : x0 + 1;
00159 double y0 = Y_pt[i] ;
00160 double y1 = (i < M-1) ? Y_pt[i+1] : y0 + 1;
00161 double wx = (x-x0)/(x1-x0) ;
00162 double wy = (y-y0)/(y1-y0) ;
00163
00164
00165 double z00 = 0.0 ;
00166 double z10 = 0.0 ;
00167 double z01 = 0.0 ;
00168 double z11 = 0.0 ;
00169
00170 if(j > -1) {
00171 if(i > -1 ) z00 = *pt ;
00172 pt++ ;
00173 if(i < M-1) z10 = *pt ;
00174 } else {
00175 pt++ ;
00176 }
00177
00178 pt += M - 1;
00179
00180 if(j < N-1) {
00181 if(i > -1 ) z01 = *pt ;
00182 pt++ ;
00183 if(i < M-1) z11 = *pt ;
00184 }
00185
00186
00187 z =
00188 (1 - wy) * ((1-wx) * z00 + wx * z01) +
00189 ( wy) * ((1-wx) * z10 + wx * z11) ;
00190 }
00191
00192 *(wI_pt + jp*Mp + ip) = z ;
00193 }
00194 }
00195 }
00196
00197
00198 else {
00199
00200
00201 for(jp = 0 ; jp < Np ; ++jp) {
00202 for(ip = 0 ; ip < Mp ; ++ip) {
00203
00204 double x = *iwXp_pt++ ;
00205 double y = *iwYp_pt++ ;
00206 double z = NaN, zx = NaN, zy = NaN ;
00207
00208
00209
00210 if(x >= Xmin && x <= Xmax &&
00211 y >= Ymin && y <= Ymax) {
00212 int j = findNeighbor(x, X_pt, N) ;
00213 int i = findNeighbor(y, Y_pt, M) ;
00214 double* pt = I_pt + j*M + i ;
00215
00216
00217 double x0 = X_pt[j] ;
00218 double x1 = X_pt[j+1] ;
00219 double y0 = Y_pt[i] ;
00220 double y1 = Y_pt[i+1] ;
00221 double wx = (x-x0)/(x1-x0) ;
00222 double wy = (y-y0)/(y1-y0) ;
00223
00224
00225 double z00 = 0.0 ;
00226 double z10 = 0.0 ;
00227 double z01 = 0.0 ;
00228 double z11 = 0.0 ;
00229
00230 if(j > -1) {
00231 if(i > -1 ) z00 = *pt ;
00232 pt++ ;
00233 if(i < M-1) z10 = *pt ;
00234 } else {
00235 pt++ ;
00236 }
00237
00238 pt += M - 1;
00239
00240 if(j < N-1) {
00241 if(i > -1 ) z01 = *pt ;
00242 pt++ ;
00243 if(i < M-1) z11 = *pt ;
00244 }
00245
00246
00247 z =
00248 (1-wy)*( (1-wx) * z00 + wx * z01) +
00249 wy*( (1-wx) * z10 + wx * z11) ;
00250
00251 zx =
00252 (1-wy) * (z01 - z00) +
00253 wy * (z11 - z10) ;
00254
00255 zy =
00256 (1-wx) * (z10 - z00) +
00257 wx * (z11 - z01) ;
00258 }
00259
00260 *(wI_pt + jp*Mp + ip) = z ;
00261 *(wIx_pt + jp*Mp + ip) = zx ;
00262 *(wIy_pt + jp*Mp + ip) = zy ;
00263 }
00264 }
00265 }
00266 }