00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined (octave_binmap_h)
00024 #define octave_binmap_h 1
00025
00026 #include "Array.h"
00027 #include "Sparse.h"
00028 #include "Array-util.h"
00029
00030 #include "bsxfun.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 template<typename R, typename X, typename Y, typename F>
00064 class bsxfun_wrapper
00065 {
00066 private:
00067 static F f;
00068
00069 public:
00070 static void
00071 set_f (const F& f_in)
00072 {
00073 f = f_in;
00074 }
00075
00076 static void
00077 op_mm (size_t n, R* r, const X* x , const Y* y)
00078 {
00079 for (size_t i = 0; i < n; i++)
00080 r[i] = f (x[i], y[i]);
00081 }
00082
00083 static void
00084 op_sm (size_t n, R* r, X x, const Y* y)
00085 {
00086 for (size_t i = 0; i < n; i++)
00087 r[i] = f (x, y[i]);
00088 }
00089
00090 static void
00091 op_ms (size_t n , R* r, const X* x, Y y)
00092 {
00093 for (size_t i = 0; i < n; i++)
00094 r[i] = f (x[i], y);
00095 }
00096 };
00097
00098
00099 template<typename R, typename X, typename Y, typename F>
00100 F bsxfun_wrapper<R, X, Y, F>::f;
00101
00102
00103
00104 template <class U, class T, class R, class F>
00105 Array<U>
00106 binmap (const T& x, const Array<R>& ya, F fcn)
00107 {
00108 octave_idx_type len = ya.numel ();
00109
00110 const R *y = ya.data ();
00111
00112 Array<U> result (ya.dims ());
00113 U *p = result.fortran_vec ();
00114
00115 octave_idx_type i;
00116 for (i = 0; i < len - 3; i += 4)
00117 {
00118 octave_quit ();
00119
00120 p[i] = fcn (x, y[i]);
00121 p[i+1] = fcn (x, y[i+1]);
00122 p[i+2] = fcn (x, y[i+2]);
00123 p[i+3] = fcn (x, y[i+3]);
00124 }
00125
00126 octave_quit ();
00127
00128 for (; i < len; i++)
00129 p[i] = fcn (x, y[i]);
00130
00131 return result;
00132 }
00133
00134
00135 template <class U, class T, class R, class F>
00136 Array<U>
00137 binmap (const Array<T>& xa, const R& y, F fcn)
00138 {
00139 octave_idx_type len = xa.numel ();
00140
00141 const R *x = xa.data ();
00142
00143 Array<U> result (xa.dims ());
00144 U *p = result.fortran_vec ();
00145
00146 octave_idx_type i;
00147 for (i = 0; i < len - 3; i += 4)
00148 {
00149 octave_quit ();
00150
00151 p[i] = fcn (x[i], y);
00152 p[i+1] = fcn (x[i+1], y);
00153 p[i+2] = fcn (x[i+2], y);
00154 p[i+3] = fcn (x[i+3], y);
00155 }
00156
00157 octave_quit ();
00158
00159 for (; i < len; i++)
00160 p[i] = fcn (x[i], y);
00161
00162 return result;
00163 }
00164
00165
00166 template <class U, class T, class R, class F>
00167 Array<U>
00168 binmap (const Array<T>& xa, const Array<R>& ya, F fcn, const char *name)
00169 {
00170 dim_vector xad = xa.dims (), yad = ya.dims ();
00171 if (xa.numel () == 1)
00172 return binmap<U, T, R, F> (xa(0), ya, fcn);
00173 else if (ya.numel () == 1)
00174 return binmap<U, T, R, F> (xa, ya(0), fcn);
00175 else if (xad != yad)
00176 {
00177 if (is_valid_bsxfun (name, xad, yad))
00178 {
00179 bsxfun_wrapper<U, T, R, F>::set_f(fcn);
00180 return do_bsxfun_op (xa, ya,
00181 bsxfun_wrapper<U, T, R, F>::op_mm,
00182 bsxfun_wrapper<U, T, R, F>::op_sm,
00183 bsxfun_wrapper<U, T, R, F>::op_ms);
00184 }
00185 else
00186 gripe_nonconformant (name, xad, yad);
00187 }
00188
00189 octave_idx_type len = xa.numel ();
00190
00191 const T *x = xa.data ();
00192 const T *y = ya.data ();
00193
00194 Array<U> result (xa.dims ());
00195 U *p = result.fortran_vec ();
00196
00197 octave_idx_type i;
00198 for (i = 0; i < len - 3; i += 4)
00199 {
00200 octave_quit ();
00201
00202 p[i] = fcn (x[i], y[i]);
00203 p[i+1] = fcn (x[i+1], y[i+1]);
00204 p[i+2] = fcn (x[i+2], y[i+2]);
00205 p[i+3] = fcn (x[i+3], y[i+3]);
00206 }
00207
00208 octave_quit ();
00209
00210 for (; i < len; i++)
00211 p[i] = fcn (x[i], y[i]);
00212
00213 return result;
00214 }
00215
00216
00217 template <class U, class T, class R, class F>
00218 Sparse<U>
00219 binmap (const T& x, const Sparse<R>& ys, F fcn)
00220 {
00221 octave_idx_type nz = ys.nnz ();
00222 Sparse<U> retval (ys.rows (), ys.cols (), nz);
00223 for (octave_idx_type i = 0; i < nz; i++)
00224 {
00225 octave_quit ();
00226 retval.xdata(i) = fcn (x, ys.data(i));
00227 }
00228
00229 octave_quit ();
00230 retval.maybe_compress ();
00231 return retval;
00232 }
00233
00234
00235 template <class U, class T, class R, class F>
00236 Sparse<U>
00237 binmap (const Sparse<T>& xs, const R& y, F fcn)
00238 {
00239 octave_idx_type nz = xs.nnz ();
00240 Sparse<U> retval (xs.rows (), xs.cols (), nz);
00241 for (octave_idx_type i = 0; i < nz; i++)
00242 {
00243 octave_quit ();
00244 retval.xdata(i) = fcn (xs.data(i), y);
00245 }
00246
00247 octave_quit ();
00248 retval.maybe_compress ();
00249 return retval;
00250 }
00251
00252
00253 template <class U, class T, class R, class F>
00254 Sparse<U>
00255 binmap (const Sparse<T>& xs, const Sparse<R>& ys, F fcn, const char *name)
00256 {
00257 if (xs.rows () == 1 && xs.cols () == 1)
00258 return binmap<U, T, R, F> (xs(0,0), ys, fcn);
00259 else if (ys.rows () == 1 && ys.cols () == 1)
00260 return binmap<U, T, R, F> (xs, ys(0,0), fcn);
00261 else if (xs.dims () != ys.dims ())
00262 gripe_nonconformant (name, xs.dims (), ys.dims ());
00263
00264 T xzero = T ();
00265 R yzero = R ();
00266
00267 U fz = fcn (xzero, yzero);
00268 if (fz == U())
00269 {
00270
00271 octave_idx_type nr = xs.rows (), nc = xs.cols ();
00272 Sparse<T> retval (nr, nc);
00273
00274 octave_idx_type nz = 0;
00275
00276 for (octave_idx_type j = 0; j < nc; j++)
00277 {
00278 octave_quit ();
00279 octave_idx_type ix = xs.cidx(j), iy = ys.cidx(j);
00280 octave_idx_type ux = xs.cidx(j+1), uy = ys.cidx(j+1);
00281 while (ix != ux || iy != uy)
00282 {
00283 octave_idx_type rx = xs.ridx(ix), ry = ys.ridx(ix);
00284 ix += rx <= ry;
00285 iy += ry <= rx;
00286 nz++;
00287 }
00288
00289 retval.xcidx(j+1) = nz;
00290 }
00291
00292
00293 retval.change_capacity (retval.xcidx(nc));
00294
00295
00296 nz = 0;
00297 for (octave_idx_type j = 0; j < nc; j++)
00298 {
00299 octave_quit ();
00300 octave_idx_type ix = xs.cidx(j), iy = ys.cidx(j);
00301 octave_idx_type ux = xs.cidx(j+1), uy = ys.cidx(j+1);
00302 while (ix != ux || iy != uy)
00303 {
00304 octave_idx_type rx = xs.ridx(ix), ry = ys.ridx(ix);
00305 if (rx == ry)
00306 {
00307 retval.xridx(nz) = rx;
00308 retval.xdata(nz) = fcn (xs.data(ix), ys.data(iy));
00309 ix++;
00310 iy++;
00311 }
00312 else if (rx < ry)
00313 {
00314 retval.xridx(nz) = rx;
00315 retval.xdata(nz) = fcn (xs.data(ix), yzero);
00316 ix++;
00317 }
00318 else if (ry < rx)
00319 {
00320 retval.xridx(nz) = ry;
00321 retval.xdata(nz) = fcn (xzero, ys.data(iy));
00322 iy++;
00323 }
00324
00325 nz++;
00326 }
00327 }
00328
00329 retval.maybe_compress ();
00330 return retval;
00331 }
00332 else
00333 return Sparse<U> (binmap<U, T, R, F> (xs.array_value (), ys.array_value (),
00334 fcn, name));
00335 }
00336
00337
00338
00339
00340
00341 template <class U, class T, class R>
00342 inline Array<U>
00343 binmap (const Array<T>& xa, const Array<R>& ya, U (*fcn) (T, R), const char *name)
00344 { return binmap<U, T, R, U (*) (T, R)> (xa, ya, fcn, name); }
00345
00346 template <class U, class T, class R>
00347 inline Array<U>
00348 binmap (const T& x, const Array<R>& ya, U (*fcn) (T, R))
00349 { return binmap<U, T, R, U (*) (T, R)> (x, ya, fcn); }
00350
00351 template <class U, class T, class R>
00352 inline Array<U>
00353 binmap (const Array<T>& xa, const R& y, U (*fcn) (T, R))
00354 { return binmap<U, T, R, U (*) (T, R)> (xa, y, fcn); }
00355
00356 template <class U, class T, class R>
00357 inline Sparse<U>
00358 binmap (const Sparse<T>& xa, const Sparse<R>& ya, U (*fcn) (T, R), const char *name)
00359 { return binmap<U, T, R, U (*) (T, R)> (xa, ya, fcn, name); }
00360
00361 template <class U, class T, class R>
00362 inline Sparse<U>
00363 binmap (const T& x, const Sparse<R>& ya, U (*fcn) (T, R))
00364 { return binmap<U, T, R, U (*) (T, R)> (x, ya, fcn); }
00365
00366 template <class U, class T, class R>
00367 inline Sparse<U>
00368 binmap (const Sparse<T>& xa, const R& y, U (*fcn) (T, R))
00369 { return binmap<U, T, R, U (*) (T, R)> (xa, y, fcn); }
00370
00371
00372
00373 template <class U, class T, class R>
00374 inline Array<U>
00375 binmap (const Array<T>& xa, const Array<R>& ya, U (*fcn) (const T&, const R&), const char *name)
00376 { return binmap<U, T, R, U (*) (const T&, const R&)> (xa, ya, fcn, name); }
00377
00378 template <class U, class T, class R>
00379 inline Array<U>
00380 binmap (const T& x, const Array<R>& ya, U (*fcn) (const T&, const R&))
00381 { return binmap<U, T, R, U (*) (const T&, const R&)> (x, ya, fcn); }
00382
00383 template <class U, class T, class R>
00384 inline Array<U>
00385 binmap (const Array<T>& xa, const R& y, U (*fcn) (const T&, const R&))
00386 { return binmap<U, T, R, U (*) (const T&, const R&)> (xa, y, fcn); }
00387
00388 template <class U, class T, class R>
00389 inline Sparse<U>
00390 binmap (const Sparse<T>& xa, const Sparse<R>& ya, U (*fcn) (const T&, const R&), const char *name)
00391 { return binmap<U, T, R, U (*) (const T&, const R&)> (xa, ya, fcn, name); }
00392
00393 template <class U, class T, class R>
00394 inline Sparse<U>
00395 binmap (const T& x, const Sparse<R>& ya, U (*fcn) (const T&, const R&))
00396 { return binmap<U, T, R, U (*) (const T&, const R&)> (x, ya, fcn); }
00397
00398 template <class U, class T, class R>
00399 inline Sparse<U>
00400 binmap (const Sparse<T>& xa, const R& y, U (*fcn) (const T&, const R&))
00401 { return binmap<U, T, R, U (*) (const T&, const R&)> (xa, y, fcn); }
00402
00403
00404
00405 template <class U, class T, class R>
00406 inline Array<U>
00407 binmap (const Array<T>& xa, const Array<R>& ya, U (*fcn) (const T&, R), const char *name)
00408 { return binmap<U, T, R, U (*) (const T&, R)> (xa, ya, fcn, name); }
00409
00410 template <class U, class T, class R>
00411 inline Array<U>
00412 binmap (const T& x, const Array<R>& ya, U (*fcn) (const T&, R))
00413 { return binmap<U, T, R, U (*) (const T&, R)> (x, ya, fcn); }
00414
00415 template <class U, class T, class R>
00416 inline Array<U>
00417 binmap (const Array<T>& xa, const R& y, U (*fcn) (const T&, R))
00418 { return binmap<U, T, R, U (*) (const T&, R)> (xa, y, fcn); }
00419
00420 template <class U, class T, class R>
00421 inline Sparse<U>
00422 binmap (const Sparse<T>& xa, const Sparse<R>& ya, U (*fcn) (const T&, R), const char *name)
00423 { return binmap<U, T, R, U (*) (const T&, R)> (xa, ya, fcn, name); }
00424
00425 template <class U, class T, class R>
00426 inline Sparse<U>
00427 binmap (const T& x, const Sparse<R>& ya, U (*fcn) (const T&, R))
00428 { return binmap<U, T, R, U (*) (const T&, R)> (x, ya, fcn); }
00429
00430 template <class U, class T, class R>
00431 inline Sparse<U>
00432 binmap (const Sparse<T>& xa, const R& y, U (*fcn) (const T&, R))
00433 { return binmap<U, T, R, U (*) (const T&, R)> (xa, y, fcn); }
00434
00435
00436
00437 template <class U, class T, class R>
00438 inline Array<U>
00439 binmap (const Array<T>& xa, const Array<R>& ya, U (*fcn) (T, const R&), const char *name)
00440 { return binmap<U, T, R, U (*) (T, const R&)> (xa, ya, fcn, name); }
00441
00442 template <class U, class T, class R>
00443 inline Array<U>
00444 binmap (const T& x, const Array<R>& ya, U (*fcn) (T, const R&))
00445 { return binmap<U, T, R, U (*) (T, const R&)> (x, ya, fcn); }
00446
00447 template <class U, class T, class R>
00448 inline Array<U>
00449 binmap (const Array<T>& xa, const R& y, U (*fcn) (T, const R&))
00450 { return binmap<U, T, R, U (*) (T, const R&)> (xa, y, fcn); }
00451
00452 template <class U, class T, class R>
00453 inline Sparse<U>
00454 binmap (const Sparse<T>& xa, const Sparse<R>& ya, U (*fcn) (T, const R&), const char *name)
00455 { return binmap<U, T, R, U (*) (T, const R&)> (xa, ya, fcn, name); }
00456
00457 template <class U, class T, class R>
00458 inline Sparse<U>
00459 binmap (const T& x, const Sparse<R>& ya, U (*fcn) (T, const R&))
00460 { return binmap<U, T, R, U (*) (T, const R&)> (x, ya, fcn); }
00461
00462 template <class U, class T, class R>
00463 inline Sparse<U>
00464 binmap (const Sparse<T>& xa, const R& y, U (*fcn) (T, const R&))
00465 { return binmap<U, T, R, U (*) (T, const R&)> (xa, y, fcn); }
00466
00467 #endif