00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <cfloat>
00030
00031 #include <vector>
00032
00033 #include "Array-util.h"
00034 #include "dNDArray.h"
00035 #include "f77-fcn.h"
00036 #include "functor.h"
00037 #include "lo-error.h"
00038 #include "lo-ieee.h"
00039 #include "lo-mappers.h"
00040 #include "mx-base.h"
00041 #include "mx-op-defs.h"
00042 #include "oct-fftw.h"
00043 #include "oct-locbuf.h"
00044
00045 #include "bsxfun-defs.cc"
00046
00047 NDArray::NDArray (const Array<octave_idx_type>& a, bool zero_based,
00048 bool negative_to_nan)
00049 {
00050 const octave_idx_type *pa = a.fortran_vec ();
00051 resize (a.dims ());
00052 double *ptmp = fortran_vec ();
00053 if (negative_to_nan)
00054 {
00055 double nan_val = lo_ieee_nan_value ();
00056
00057 if (zero_based)
00058 for (octave_idx_type i = 0; i < a.numel (); i++)
00059 {
00060 double val = static_cast<double>
00061 (pa[i] + static_cast<octave_idx_type> (1));
00062 if (val <= 0)
00063 ptmp[i] = nan_val;
00064 else
00065 ptmp[i] = val;
00066 }
00067 else
00068 for (octave_idx_type i = 0; i < a.numel (); i++)
00069 {
00070 double val = static_cast<double> (pa[i]);
00071 if (val <= 0)
00072 ptmp[i] = nan_val;
00073 else
00074 ptmp[i] = val;
00075 }
00076 }
00077 else
00078 {
00079 if (zero_based)
00080 for (octave_idx_type i = 0; i < a.numel (); i++)
00081 ptmp[i] = static_cast<double>
00082 (pa[i] + static_cast<octave_idx_type> (1));
00083 else
00084 for (octave_idx_type i = 0; i < a.numel (); i++)
00085 ptmp[i] = static_cast<double> (pa[i]);
00086 }
00087 }
00088
00089 NDArray::NDArray (const charNDArray& a)
00090 : MArray<double> (a.dims ())
00091 {
00092 octave_idx_type n = a.numel ();
00093 for (octave_idx_type i = 0; i < n; i++)
00094 xelem (i) = static_cast<unsigned char> (a(i));
00095 }
00096
00097 #if defined (HAVE_FFTW)
00098
00099 ComplexNDArray
00100 NDArray::fourier (int dim) const
00101 {
00102 dim_vector dv = dims ();
00103
00104 if (dim > dv.length () || dim < 0)
00105 return ComplexNDArray ();
00106
00107 octave_idx_type stride = 1;
00108 octave_idx_type n = dv(dim);
00109
00110 for (int i = 0; i < dim; i++)
00111 stride *= dv(i);
00112
00113 octave_idx_type howmany = numel () / dv (dim);
00114 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00115 octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
00116 octave_idx_type dist = (stride == 1 ? n : 1);
00117
00118 const double *in (fortran_vec ());
00119 ComplexNDArray retval (dv);
00120 Complex *out (retval.fortran_vec ());
00121
00122
00123 for (octave_idx_type k = 0; k < nloop; k++)
00124 octave_fftw::fft (in + k * stride * n, out + k * stride * n,
00125 n, howmany, stride, dist);
00126
00127 return retval;
00128 }
00129
00130 ComplexNDArray
00131 NDArray::ifourier (int dim) const
00132 {
00133 dim_vector dv = dims ();
00134
00135 if (dim > dv.length () || dim < 0)
00136 return ComplexNDArray ();
00137
00138 octave_idx_type stride = 1;
00139 octave_idx_type n = dv(dim);
00140
00141 for (int i = 0; i < dim; i++)
00142 stride *= dv(i);
00143
00144 octave_idx_type howmany = numel () / dv (dim);
00145 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00146 octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
00147 octave_idx_type dist = (stride == 1 ? n : 1);
00148
00149 ComplexNDArray retval (*this);
00150 Complex *out (retval.fortran_vec ());
00151
00152
00153 for (octave_idx_type k = 0; k < nloop; k++)
00154 octave_fftw::ifft (out + k * stride * n, out + k * stride * n,
00155 n, howmany, stride, dist);
00156
00157 return retval;
00158 }
00159
00160 ComplexNDArray
00161 NDArray::fourier2d (void) const
00162 {
00163 dim_vector dv = dims();
00164 if (dv.length () < 2)
00165 return ComplexNDArray ();
00166
00167 dim_vector dv2(dv(0), dv(1));
00168 const double *in = fortran_vec ();
00169 ComplexNDArray retval (dv);
00170 Complex *out = retval.fortran_vec ();
00171 octave_idx_type howmany = numel() / dv(0) / dv(1);
00172 octave_idx_type dist = dv(0) * dv(1);
00173
00174 for (octave_idx_type i=0; i < howmany; i++)
00175 octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
00176
00177 return retval;
00178 }
00179
00180 ComplexNDArray
00181 NDArray::ifourier2d (void) const
00182 {
00183 dim_vector dv = dims();
00184 if (dv.length () < 2)
00185 return ComplexNDArray ();
00186
00187 dim_vector dv2(dv(0), dv(1));
00188 ComplexNDArray retval (*this);
00189 Complex *out = retval.fortran_vec ();
00190 octave_idx_type howmany = numel() / dv(0) / dv(1);
00191 octave_idx_type dist = dv(0) * dv(1);
00192
00193 for (octave_idx_type i=0; i < howmany; i++)
00194 octave_fftw::ifftNd (out + i*dist, out + i*dist, 2, dv2);
00195
00196 return retval;
00197 }
00198
00199 ComplexNDArray
00200 NDArray::fourierNd (void) const
00201 {
00202 dim_vector dv = dims ();
00203 int rank = dv.length ();
00204
00205 const double *in (fortran_vec ());
00206 ComplexNDArray retval (dv);
00207 Complex *out (retval.fortran_vec ());
00208
00209 octave_fftw::fftNd (in, out, rank, dv);
00210
00211 return retval;
00212 }
00213
00214 ComplexNDArray
00215 NDArray::ifourierNd (void) const
00216 {
00217 dim_vector dv = dims ();
00218 int rank = dv.length ();
00219
00220 ComplexNDArray tmp (*this);
00221 Complex *in (tmp.fortran_vec ());
00222 ComplexNDArray retval (dv);
00223 Complex *out (retval.fortran_vec ());
00224
00225 octave_fftw::ifftNd (in, out, rank, dv);
00226
00227 return retval;
00228 }
00229
00230 #else
00231
00232 extern "C"
00233 {
00234
00235
00236
00237
00238
00239 F77_RET_T
00240 F77_FUNC (zffti, ZFFTI) (const octave_idx_type&, Complex*);
00241
00242 F77_RET_T
00243 F77_FUNC (zfftf, ZFFTF) (const octave_idx_type&, Complex*, Complex*);
00244
00245 F77_RET_T
00246 F77_FUNC (zfftb, ZFFTB) (const octave_idx_type&, Complex*, Complex*);
00247 }
00248
00249 ComplexNDArray
00250 NDArray::fourier (int dim) const
00251 {
00252 dim_vector dv = dims ();
00253
00254 if (dim > dv.length () || dim < 0)
00255 return ComplexNDArray ();
00256
00257 ComplexNDArray retval (dv);
00258 octave_idx_type npts = dv(dim);
00259 octave_idx_type nn = 4*npts+15;
00260 Array<Complex> wsave (nn);
00261 Complex *pwsave = wsave.fortran_vec ();
00262
00263 OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
00264
00265 octave_idx_type stride = 1;
00266
00267 for (int i = 0; i < dim; i++)
00268 stride *= dv(i);
00269
00270 octave_idx_type howmany = numel () / npts;
00271 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00272 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00273 octave_idx_type dist = (stride == 1 ? npts : 1);
00274
00275 F77_FUNC (zffti, ZFFTI) (npts, pwsave);
00276
00277 for (octave_idx_type k = 0; k < nloop; k++)
00278 {
00279 for (octave_idx_type j = 0; j < howmany; j++)
00280 {
00281 octave_quit ();
00282
00283 for (octave_idx_type i = 0; i < npts; i++)
00284 tmp[i] = elem((i + k*npts)*stride + j*dist);
00285
00286 F77_FUNC (zfftf, ZFFTF) (npts, tmp, pwsave);
00287
00288 for (octave_idx_type i = 0; i < npts; i++)
00289 retval ((i + k*npts)*stride + j*dist) = tmp[i];
00290 }
00291 }
00292
00293 return retval;
00294 }
00295
00296 ComplexNDArray
00297 NDArray::ifourier (int dim) const
00298 {
00299 dim_vector dv = dims ();
00300
00301 if (dim > dv.length () || dim < 0)
00302 return ComplexNDArray ();
00303
00304 ComplexNDArray retval (dv);
00305 octave_idx_type npts = dv(dim);
00306 octave_idx_type nn = 4*npts+15;
00307 Array<Complex> wsave (nn);
00308 Complex *pwsave = wsave.fortran_vec ();
00309
00310 OCTAVE_LOCAL_BUFFER (Complex, tmp, npts);
00311
00312 octave_idx_type stride = 1;
00313
00314 for (int i = 0; i < dim; i++)
00315 stride *= dv(i);
00316
00317 octave_idx_type howmany = numel () / npts;
00318 howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00319 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00320 octave_idx_type dist = (stride == 1 ? npts : 1);
00321
00322 F77_FUNC (zffti, ZFFTI) (npts, pwsave);
00323
00324 for (octave_idx_type k = 0; k < nloop; k++)
00325 {
00326 for (octave_idx_type j = 0; j < howmany; j++)
00327 {
00328 octave_quit ();
00329
00330 for (octave_idx_type i = 0; i < npts; i++)
00331 tmp[i] = elem((i + k*npts)*stride + j*dist);
00332
00333 F77_FUNC (zfftb, ZFFTB) (npts, tmp, pwsave);
00334
00335 for (octave_idx_type i = 0; i < npts; i++)
00336 retval ((i + k*npts)*stride + j*dist) = tmp[i] /
00337 static_cast<double> (npts);
00338 }
00339 }
00340
00341 return retval;
00342 }
00343
00344 ComplexNDArray
00345 NDArray::fourier2d (void) const
00346 {
00347 dim_vector dv = dims();
00348 dim_vector dv2 (dv(0), dv(1));
00349 int rank = 2;
00350 ComplexNDArray retval (*this);
00351 octave_idx_type stride = 1;
00352
00353 for (int i = 0; i < rank; i++)
00354 {
00355 octave_idx_type npts = dv2(i);
00356 octave_idx_type nn = 4*npts+15;
00357 Array<Complex> wsave (nn);
00358 Complex *pwsave = wsave.fortran_vec ();
00359 Array<Complex> row (npts);
00360 Complex *prow = row.fortran_vec ();
00361
00362 octave_idx_type howmany = numel () / npts;
00363 howmany = (stride == 1 ? howmany :
00364 (howmany > stride ? stride : howmany));
00365 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00366 octave_idx_type dist = (stride == 1 ? npts : 1);
00367
00368 F77_FUNC (zffti, ZFFTI) (npts, pwsave);
00369
00370 for (octave_idx_type k = 0; k < nloop; k++)
00371 {
00372 for (octave_idx_type j = 0; j < howmany; j++)
00373 {
00374 octave_quit ();
00375
00376 for (octave_idx_type l = 0; l < npts; l++)
00377 prow[l] = retval ((l + k*npts)*stride + j*dist);
00378
00379 F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
00380
00381 for (octave_idx_type l = 0; l < npts; l++)
00382 retval ((l + k*npts)*stride + j*dist) = prow[l];
00383 }
00384 }
00385
00386 stride *= dv2(i);
00387 }
00388
00389 return retval;
00390 }
00391
00392 ComplexNDArray
00393 NDArray::ifourier2d (void) const
00394 {
00395 dim_vector dv = dims();
00396 dim_vector dv2 (dv(0), dv(1));
00397 int rank = 2;
00398 ComplexNDArray retval (*this);
00399 octave_idx_type stride = 1;
00400
00401 for (int i = 0; i < rank; i++)
00402 {
00403 octave_idx_type npts = dv2(i);
00404 octave_idx_type nn = 4*npts+15;
00405 Array<Complex> wsave (nn);
00406 Complex *pwsave = wsave.fortran_vec ();
00407 Array<Complex> row (npts);
00408 Complex *prow = row.fortran_vec ();
00409
00410 octave_idx_type howmany = numel () / npts;
00411 howmany = (stride == 1 ? howmany :
00412 (howmany > stride ? stride : howmany));
00413 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00414 octave_idx_type dist = (stride == 1 ? npts : 1);
00415
00416 F77_FUNC (zffti, ZFFTI) (npts, pwsave);
00417
00418 for (octave_idx_type k = 0; k < nloop; k++)
00419 {
00420 for (octave_idx_type j = 0; j < howmany; j++)
00421 {
00422 octave_quit ();
00423
00424 for (octave_idx_type l = 0; l < npts; l++)
00425 prow[l] = retval ((l + k*npts)*stride + j*dist);
00426
00427 F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
00428
00429 for (octave_idx_type l = 0; l < npts; l++)
00430 retval ((l + k*npts)*stride + j*dist) = prow[l] /
00431 static_cast<double> (npts);
00432 }
00433 }
00434
00435 stride *= dv2(i);
00436 }
00437
00438 return retval;
00439 }
00440
00441 ComplexNDArray
00442 NDArray::fourierNd (void) const
00443 {
00444 dim_vector dv = dims ();
00445 int rank = dv.length ();
00446 ComplexNDArray retval (*this);
00447 octave_idx_type stride = 1;
00448
00449 for (int i = 0; i < rank; i++)
00450 {
00451 octave_idx_type npts = dv(i);
00452 octave_idx_type nn = 4*npts+15;
00453 Array<Complex> wsave (nn);
00454 Complex *pwsave = wsave.fortran_vec ();
00455 Array<Complex> row (npts);
00456 Complex *prow = row.fortran_vec ();
00457
00458 octave_idx_type howmany = numel () / npts;
00459 howmany = (stride == 1 ? howmany :
00460 (howmany > stride ? stride : howmany));
00461 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00462 octave_idx_type dist = (stride == 1 ? npts : 1);
00463
00464 F77_FUNC (zffti, ZFFTI) (npts, pwsave);
00465
00466 for (octave_idx_type k = 0; k < nloop; k++)
00467 {
00468 for (octave_idx_type j = 0; j < howmany; j++)
00469 {
00470 octave_quit ();
00471
00472 for (octave_idx_type l = 0; l < npts; l++)
00473 prow[l] = retval ((l + k*npts)*stride + j*dist);
00474
00475 F77_FUNC (zfftf, ZFFTF) (npts, prow, pwsave);
00476
00477 for (octave_idx_type l = 0; l < npts; l++)
00478 retval ((l + k*npts)*stride + j*dist) = prow[l];
00479 }
00480 }
00481
00482 stride *= dv(i);
00483 }
00484
00485 return retval;
00486 }
00487
00488 ComplexNDArray
00489 NDArray::ifourierNd (void) const
00490 {
00491 dim_vector dv = dims ();
00492 int rank = dv.length ();
00493 ComplexNDArray retval (*this);
00494 octave_idx_type stride = 1;
00495
00496 for (int i = 0; i < rank; i++)
00497 {
00498 octave_idx_type npts = dv(i);
00499 octave_idx_type nn = 4*npts+15;
00500 Array<Complex> wsave (nn);
00501 Complex *pwsave = wsave.fortran_vec ();
00502 Array<Complex> row (npts);
00503 Complex *prow = row.fortran_vec ();
00504
00505 octave_idx_type howmany = numel () / npts;
00506 howmany = (stride == 1 ? howmany :
00507 (howmany > stride ? stride : howmany));
00508 octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00509 octave_idx_type dist = (stride == 1 ? npts : 1);
00510
00511 F77_FUNC (zffti, ZFFTI) (npts, pwsave);
00512
00513 for (octave_idx_type k = 0; k < nloop; k++)
00514 {
00515 for (octave_idx_type j = 0; j < howmany; j++)
00516 {
00517 octave_quit ();
00518
00519 for (octave_idx_type l = 0; l < npts; l++)
00520 prow[l] = retval ((l + k*npts)*stride + j*dist);
00521
00522 F77_FUNC (zfftb, ZFFTB) (npts, prow, pwsave);
00523
00524 for (octave_idx_type l = 0; l < npts; l++)
00525 retval ((l + k*npts)*stride + j*dist) = prow[l] /
00526 static_cast<double> (npts);
00527 }
00528 }
00529
00530 stride *= dv(i);
00531 }
00532
00533 return retval;
00534 }
00535
00536 #endif
00537
00538
00539
00540 boolNDArray
00541 NDArray::operator ! (void) const
00542 {
00543 if (any_element_is_nan ())
00544 gripe_nan_to_logical_conversion ();
00545
00546 return do_mx_unary_op<bool, double> (*this, mx_inline_not);
00547 }
00548
00549 bool
00550 NDArray::any_element_is_negative (bool neg_zero) const
00551 {
00552 return (neg_zero ? test_all (xnegative_sign)
00553 : do_mx_check<double> (*this, mx_inline_any_negative));
00554 }
00555
00556 bool
00557 NDArray::any_element_is_positive (bool neg_zero) const
00558 {
00559 return (neg_zero ? test_all (xpositive_sign)
00560 : do_mx_check<double> (*this, mx_inline_any_positive));
00561 }
00562
00563 bool
00564 NDArray::any_element_is_nan (void) const
00565 {
00566 return do_mx_check<double> (*this, mx_inline_any_nan);
00567 }
00568
00569 bool
00570 NDArray::any_element_is_inf_or_nan (void) const
00571 {
00572 return ! do_mx_check<double> (*this, mx_inline_all_finite);
00573 }
00574
00575 bool
00576 NDArray::any_element_not_one_or_zero (void) const
00577 {
00578 return ! test_all (xis_one_or_zero);
00579 }
00580
00581 bool
00582 NDArray::all_elements_are_zero (void) const
00583 {
00584 return test_all (xis_zero);
00585 }
00586
00587 bool
00588 NDArray::all_elements_are_int_or_inf_or_nan (void) const
00589 {
00590 return test_all (xis_int_or_inf_or_nan);
00591 }
00592
00593
00594
00595
00596 bool
00597 NDArray::all_integers (double& max_val, double& min_val) const
00598 {
00599 octave_idx_type nel = nelem ();
00600
00601 if (nel > 0)
00602 {
00603 max_val = elem (0);
00604 min_val = elem (0);
00605 }
00606 else
00607 return false;
00608
00609 for (octave_idx_type i = 0; i < nel; i++)
00610 {
00611 double val = elem (i);
00612
00613 if (val > max_val)
00614 max_val = val;
00615
00616 if (val < min_val)
00617 min_val = val;
00618
00619 if (! xisinteger (val))
00620 return false;
00621 }
00622
00623 return true;
00624 }
00625
00626 bool
00627 NDArray::all_integers (void) const
00628 {
00629 return test_all (xisinteger);
00630 }
00631
00632 bool
00633 NDArray::too_large_for_float (void) const
00634 {
00635 return test_all (xtoo_large_for_float);
00636 }
00637
00638
00639
00640 boolNDArray
00641 NDArray::all (int dim) const
00642 {
00643 return do_mx_red_op<bool, double> (*this, dim, mx_inline_all);
00644 }
00645
00646 boolNDArray
00647 NDArray::any (int dim) const
00648 {
00649 return do_mx_red_op<bool, double> (*this, dim, mx_inline_any);
00650 }
00651
00652 NDArray
00653 NDArray::cumprod (int dim) const
00654 {
00655 return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumprod);
00656 }
00657
00658 NDArray
00659 NDArray::cumsum (int dim) const
00660 {
00661 return do_mx_cum_op<double, double> (*this, dim, mx_inline_cumsum);
00662 }
00663
00664 NDArray
00665 NDArray::prod (int dim) const
00666 {
00667 return do_mx_red_op<double, double> (*this, dim, mx_inline_prod);
00668 }
00669
00670 NDArray
00671 NDArray::sum (int dim) const
00672 {
00673 return do_mx_red_op<double, double> (*this, dim, mx_inline_sum);
00674 }
00675
00676 NDArray
00677 NDArray::xsum (int dim) const
00678 {
00679 return do_mx_red_op<double, double> (*this, dim, mx_inline_xsum);
00680 }
00681
00682 NDArray
00683 NDArray::sumsq (int dim) const
00684 {
00685 return do_mx_red_op<double, double> (*this, dim, mx_inline_sumsq);
00686 }
00687
00688 NDArray
00689 NDArray::max (int dim) const
00690 {
00691 return do_mx_minmax_op<double> (*this, dim, mx_inline_max);
00692 }
00693
00694 NDArray
00695 NDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
00696 {
00697 return do_mx_minmax_op<double> (*this, idx_arg, dim, mx_inline_max);
00698 }
00699
00700 NDArray
00701 NDArray::min (int dim) const
00702 {
00703 return do_mx_minmax_op<double> (*this, dim, mx_inline_min);
00704 }
00705
00706 NDArray
00707 NDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
00708 {
00709 return do_mx_minmax_op<double> (*this, idx_arg, dim, mx_inline_min);
00710 }
00711
00712 NDArray
00713 NDArray::cummax (int dim) const
00714 {
00715 return do_mx_cumminmax_op<double> (*this, dim, mx_inline_cummax);
00716 }
00717
00718 NDArray
00719 NDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
00720 {
00721 return do_mx_cumminmax_op<double> (*this, idx_arg, dim, mx_inline_cummax);
00722 }
00723
00724 NDArray
00725 NDArray::cummin (int dim) const
00726 {
00727 return do_mx_cumminmax_op<double> (*this, dim, mx_inline_cummin);
00728 }
00729
00730 NDArray
00731 NDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
00732 {
00733 return do_mx_cumminmax_op<double> (*this, idx_arg, dim, mx_inline_cummin);
00734 }
00735
00736 NDArray
00737 NDArray::diff (octave_idx_type order, int dim) const
00738 {
00739 return do_mx_diff_op<double> (*this, dim, order, mx_inline_diff);
00740 }
00741
00742 NDArray
00743 NDArray::concat (const NDArray& rb, const Array<octave_idx_type>& ra_idx)
00744 {
00745 if (rb.numel () > 0)
00746 insert (rb, ra_idx);
00747 return *this;
00748 }
00749
00750 ComplexNDArray
00751 NDArray::concat (const ComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
00752 {
00753 ComplexNDArray retval (*this);
00754 if (rb.numel () > 0)
00755 retval.insert (rb, ra_idx);
00756 return retval;
00757 }
00758
00759 charNDArray
00760 NDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx)
00761 {
00762 charNDArray retval (dims ());
00763 octave_idx_type nel = numel ();
00764
00765 for (octave_idx_type i = 0; i < nel; i++)
00766 {
00767 double d = elem (i);
00768
00769 if (xisnan (d))
00770 {
00771 (*current_liboctave_error_handler)
00772 ("invalid conversion from NaN to character");
00773 return retval;
00774 }
00775 else
00776 {
00777 octave_idx_type ival = NINTbig (d);
00778
00779 if (ival < 0 || ival > UCHAR_MAX)
00780
00781
00782 ival = 0;
00783
00784 retval.elem (i) = static_cast<char>(ival);
00785 }
00786 }
00787
00788 if (rb.numel () == 0)
00789 return retval;
00790
00791 retval.insert (rb, ra_idx);
00792 return retval;
00793 }
00794
00795 NDArray
00796 real (const ComplexNDArray& a)
00797 {
00798 return do_mx_unary_op<double, Complex> (a, mx_inline_real);
00799 }
00800
00801 NDArray
00802 imag (const ComplexNDArray& a)
00803 {
00804 return do_mx_unary_op<double, Complex> (a, mx_inline_imag);
00805 }
00806
00807 NDArray&
00808 NDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c)
00809 {
00810 Array<double>::insert (a, r, c);
00811 return *this;
00812 }
00813
00814 NDArray&
00815 NDArray::insert (const NDArray& a, const Array<octave_idx_type>& ra_idx)
00816 {
00817 Array<double>::insert (a, ra_idx);
00818 return *this;
00819 }
00820
00821 NDArray
00822 NDArray::abs (void) const
00823 {
00824 return do_mx_unary_map<double, double, std::abs> (*this);
00825 }
00826
00827 boolNDArray
00828 NDArray::isnan (void) const
00829 {
00830 return do_mx_unary_map<bool, double, xisnan> (*this);
00831 }
00832
00833 boolNDArray
00834 NDArray::isinf (void) const
00835 {
00836 return do_mx_unary_map<bool, double, xisinf> (*this);
00837 }
00838
00839 boolNDArray
00840 NDArray::isfinite (void) const
00841 {
00842 return do_mx_unary_map<bool, double, xfinite> (*this);
00843 }
00844
00845 Matrix
00846 NDArray::matrix_value (void) const
00847 {
00848 Matrix retval;
00849
00850 if (ndims () == 2)
00851 retval = Matrix (Array<double> (*this));
00852 else
00853 (*current_liboctave_error_handler)
00854 ("invalid conversion of NDArray to Matrix");
00855
00856 return retval;
00857 }
00858
00859 void
00860 NDArray::increment_index (Array<octave_idx_type>& ra_idx,
00861 const dim_vector& dimensions,
00862 int start_dimension)
00863 {
00864 ::increment_index (ra_idx, dimensions, start_dimension);
00865 }
00866
00867 octave_idx_type
00868 NDArray::compute_index (Array<octave_idx_type>& ra_idx,
00869 const dim_vector& dimensions)
00870 {
00871 return ::compute_index (ra_idx, dimensions);
00872 }
00873
00874 NDArray
00875 NDArray::diag (octave_idx_type k) const
00876 {
00877 return MArray<double>::diag (k);
00878 }
00879
00880
00881 std::ostream&
00882 operator << (std::ostream& os, const NDArray& a)
00883 {
00884 octave_idx_type nel = a.nelem ();
00885
00886 for (octave_idx_type i = 0; i < nel; i++)
00887 {
00888 os << " ";
00889 octave_write_double (os, a.elem (i));
00890 os << "\n";
00891 }
00892 return os;
00893 }
00894
00895 std::istream&
00896 operator >> (std::istream& is, NDArray& a)
00897 {
00898 octave_idx_type nel = a.nelem ();
00899
00900 if (nel > 0)
00901 {
00902 double tmp;
00903 for (octave_idx_type i = 0; i < nel; i++)
00904 {
00905 tmp = octave_read_value<double> (is);
00906 if (is)
00907 a.elem (i) = tmp;
00908 else
00909 goto done;
00910 }
00911 }
00912
00913 done:
00914
00915 return is;
00916 }
00917
00918 MINMAX_FCNS (NDArray, double)
00919
00920 NDS_CMP_OPS (NDArray, double)
00921 NDS_BOOL_OPS (NDArray, double)
00922
00923 SND_CMP_OPS (double, NDArray)
00924 SND_BOOL_OPS (double, NDArray)
00925
00926 NDND_CMP_OPS (NDArray, NDArray)
00927 NDND_BOOL_OPS (NDArray, NDArray)
00928
00929 BSXFUN_STDOP_DEFS_MXLOOP (NDArray)
00930 BSXFUN_STDREL_DEFS_MXLOOP (NDArray)
00931
00932 BSXFUN_OP_DEF_MXLOOP (pow, NDArray, mx_inline_pow)
00933 BSXFUN_OP2_DEF_MXLOOP (pow, ComplexNDArray, ComplexNDArray,
00934 NDArray, mx_inline_pow)
00935 BSXFUN_OP2_DEF_MXLOOP (pow, ComplexNDArray, NDArray,
00936 ComplexNDArray, mx_inline_pow)