fNDArray.cc

Go to the documentation of this file.
00001 // N-D Array  manipulations.
00002 /*
00003 
00004 Copyright (C) 1996-2012 John W. Eaton
00005 Copyright (C) 2009 VZLU Prague, a.s.
00006 
00007 This file is part of Octave.
00008 
00009 Octave is free software; you can redistribute it and/or modify it
00010 under the terms of the GNU General Public License as published by the
00011 Free Software Foundation; either version 3 of the License, or (at your
00012 option) any later version.
00013 
00014 Octave is distributed in the hope that it will be useful, but WITHOUT
00015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00016 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00017 for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with Octave; see the file COPYING.  If not, see
00021 <http://www.gnu.org/licenses/>.
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 "f77-fcn.h"
00035 #include "fNDArray.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 FloatNDArray::FloatNDArray (const charNDArray& a)
00048   : MArray<float> (a.dims ())
00049 {
00050   octave_idx_type n = a.numel ();
00051   for (octave_idx_type i = 0; i < n; i++)
00052     xelem (i) = static_cast<unsigned char> (a(i));
00053 }
00054 
00055 #if defined (HAVE_FFTW)
00056 
00057 FloatComplexNDArray
00058 FloatNDArray::fourier (int dim) const
00059 {
00060   dim_vector dv = dims ();
00061 
00062   if (dim > dv.length () || dim < 0)
00063     return FloatComplexNDArray ();
00064 
00065   octave_idx_type stride = 1;
00066   octave_idx_type n = dv(dim);
00067 
00068   for (int i = 0; i < dim; i++)
00069     stride *= dv(i);
00070 
00071   octave_idx_type howmany = numel () / dv (dim);
00072   howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00073   octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
00074   octave_idx_type dist = (stride == 1 ? n : 1);
00075 
00076   const float *in (fortran_vec ());
00077   FloatComplexNDArray retval (dv);
00078   FloatComplex *out (retval.fortran_vec ());
00079 
00080   // Need to be careful here about the distance between fft's
00081   for (octave_idx_type k = 0; k < nloop; k++)
00082     octave_fftw::fft (in + k * stride * n, out + k * stride * n,
00083                       n, howmany, stride, dist);
00084 
00085   return retval;
00086 }
00087 
00088 FloatComplexNDArray
00089 FloatNDArray::ifourier (int dim) const
00090 {
00091   dim_vector dv = dims ();
00092 
00093   if (dim > dv.length () || dim < 0)
00094     return FloatComplexNDArray ();
00095 
00096   octave_idx_type stride = 1;
00097   octave_idx_type n = dv(dim);
00098 
00099   for (int i = 0; i < dim; i++)
00100     stride *= dv(i);
00101 
00102   octave_idx_type howmany = numel () / dv (dim);
00103   howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00104   octave_idx_type nloop = (stride == 1 ? 1 : numel () / dv (dim) / stride);
00105   octave_idx_type dist = (stride == 1 ? n : 1);
00106 
00107   FloatComplexNDArray retval (*this);
00108   FloatComplex *out (retval.fortran_vec ());
00109 
00110   // Need to be careful here about the distance between fft's
00111   for (octave_idx_type k = 0; k < nloop; k++)
00112     octave_fftw::ifft (out + k * stride * n, out + k * stride * n,
00113                       n, howmany, stride, dist);
00114 
00115   return retval;
00116 }
00117 
00118 FloatComplexNDArray
00119 FloatNDArray::fourier2d (void) const
00120 {
00121   dim_vector dv = dims();
00122   if (dv.length () < 2)
00123     return FloatComplexNDArray ();
00124 
00125   dim_vector dv2(dv(0), dv(1));
00126   const float *in = fortran_vec ();
00127   FloatComplexNDArray retval (dv);
00128   FloatComplex *out = retval.fortran_vec ();
00129   octave_idx_type howmany = numel() / dv(0) / dv(1);
00130   octave_idx_type dist = dv(0) * dv(1);
00131 
00132   for (octave_idx_type i=0; i < howmany; i++)
00133     octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
00134 
00135   return retval;
00136 }
00137 
00138 FloatComplexNDArray
00139 FloatNDArray::ifourier2d (void) const
00140 {
00141   dim_vector dv = dims();
00142   if (dv.length () < 2)
00143     return FloatComplexNDArray ();
00144 
00145   dim_vector dv2(dv(0), dv(1));
00146   FloatComplexNDArray retval (*this);
00147   FloatComplex *out = retval.fortran_vec ();
00148   octave_idx_type howmany = numel() / dv(0) / dv(1);
00149   octave_idx_type dist = dv(0) * dv(1);
00150 
00151   for (octave_idx_type i=0; i < howmany; i++)
00152     octave_fftw::ifftNd (out + i*dist, out + i*dist, 2, dv2);
00153 
00154   return retval;
00155 }
00156 
00157 FloatComplexNDArray
00158 FloatNDArray::fourierNd (void) const
00159 {
00160   dim_vector dv = dims ();
00161   int rank = dv.length ();
00162 
00163   const float *in (fortran_vec ());
00164   FloatComplexNDArray retval (dv);
00165   FloatComplex *out (retval.fortran_vec ());
00166 
00167   octave_fftw::fftNd (in, out, rank, dv);
00168 
00169   return retval;
00170 }
00171 
00172 FloatComplexNDArray
00173 FloatNDArray::ifourierNd (void) const
00174 {
00175   dim_vector dv = dims ();
00176   int rank = dv.length ();
00177 
00178   FloatComplexNDArray tmp (*this);
00179   FloatComplex *in (tmp.fortran_vec ());
00180   FloatComplexNDArray retval (dv);
00181   FloatComplex *out (retval.fortran_vec ());
00182 
00183   octave_fftw::ifftNd (in, out, rank, dv);
00184 
00185   return retval;
00186 }
00187 
00188 #else
00189 
00190 extern "C"
00191 {
00192   // Note that the original complex fft routines were not written for
00193   // float complex arguments.  They have been modified by adding an
00194   // implicit float precision (a-h,o-z) statement at the beginning of
00195   // each subroutine.
00196 
00197   F77_RET_T
00198   F77_FUNC (cffti, CFFTI) (const octave_idx_type&, FloatComplex*);
00199 
00200   F77_RET_T
00201   F77_FUNC (cfftf, CFFTF) (const octave_idx_type&, FloatComplex*,
00202                            FloatComplex*);
00203 
00204   F77_RET_T
00205   F77_FUNC (cfftb, CFFTB) (const octave_idx_type&, FloatComplex*,
00206                            FloatComplex*);
00207 }
00208 
00209 FloatComplexNDArray
00210 FloatNDArray::fourier (int dim) const
00211 {
00212   dim_vector dv = dims ();
00213 
00214   if (dim > dv.length () || dim < 0)
00215     return FloatComplexNDArray ();
00216 
00217   FloatComplexNDArray retval (dv);
00218   octave_idx_type npts = dv(dim);
00219   octave_idx_type nn = 4*npts+15;
00220   Array<FloatComplex> wsave (nn);
00221   FloatComplex *pwsave = wsave.fortran_vec ();
00222 
00223   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
00224 
00225   octave_idx_type stride = 1;
00226 
00227   for (int i = 0; i < dim; i++)
00228     stride *= dv(i);
00229 
00230   octave_idx_type howmany = numel () / npts;
00231   howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00232   octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00233   octave_idx_type dist = (stride == 1 ? npts : 1);
00234 
00235   F77_FUNC (cffti, CFFTI) (npts, pwsave);
00236 
00237   for (octave_idx_type k = 0; k < nloop; k++)
00238     {
00239       for (octave_idx_type j = 0; j < howmany; j++)
00240         {
00241           octave_quit ();
00242 
00243           for (octave_idx_type i = 0; i < npts; i++)
00244             tmp[i] = elem((i + k*npts)*stride + j*dist);
00245 
00246           F77_FUNC (cfftf, CFFTF) (npts, tmp, pwsave);
00247 
00248           for (octave_idx_type i = 0; i < npts; i++)
00249             retval ((i + k*npts)*stride + j*dist) = tmp[i];
00250         }
00251     }
00252 
00253   return retval;
00254 }
00255 
00256 FloatComplexNDArray
00257 FloatNDArray::ifourier (int dim) const
00258 {
00259   dim_vector dv = dims ();
00260 
00261   if (dim > dv.length () || dim < 0)
00262     return FloatComplexNDArray ();
00263 
00264   FloatComplexNDArray retval (dv);
00265   octave_idx_type npts = dv(dim);
00266   octave_idx_type nn = 4*npts+15;
00267   Array<FloatComplex> wsave (nn);
00268   FloatComplex *pwsave = wsave.fortran_vec ();
00269 
00270   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
00271 
00272   octave_idx_type stride = 1;
00273 
00274   for (int i = 0; i < dim; i++)
00275     stride *= dv(i);
00276 
00277   octave_idx_type howmany = numel () / npts;
00278   howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00279   octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00280   octave_idx_type dist = (stride == 1 ? npts : 1);
00281 
00282   F77_FUNC (cffti, CFFTI) (npts, pwsave);
00283 
00284   for (octave_idx_type k = 0; k < nloop; k++)
00285     {
00286       for (octave_idx_type j = 0; j < howmany; j++)
00287         {
00288           octave_quit ();
00289 
00290           for (octave_idx_type i = 0; i < npts; i++)
00291             tmp[i] = elem((i + k*npts)*stride + j*dist);
00292 
00293           F77_FUNC (cfftb, CFFTB) (npts, tmp, pwsave);
00294 
00295           for (octave_idx_type i = 0; i < npts; i++)
00296             retval ((i + k*npts)*stride + j*dist) = tmp[i] /
00297               static_cast<float> (npts);
00298         }
00299     }
00300 
00301   return retval;
00302 }
00303 
00304 FloatComplexNDArray
00305 FloatNDArray::fourier2d (void) const
00306 {
00307   dim_vector dv = dims();
00308   dim_vector dv2 (dv(0), dv(1));
00309   int rank = 2;
00310   FloatComplexNDArray retval (*this);
00311   octave_idx_type stride = 1;
00312 
00313   for (int i = 0; i < rank; i++)
00314     {
00315       octave_idx_type npts = dv2(i);
00316       octave_idx_type nn = 4*npts+15;
00317       Array<FloatComplex> wsave (nn);
00318       FloatComplex *pwsave = wsave.fortran_vec ();
00319       Array<FloatComplex> row (npts);
00320       FloatComplex *prow = row.fortran_vec ();
00321 
00322       octave_idx_type howmany = numel () / npts;
00323       howmany = (stride == 1 ? howmany :
00324                  (howmany > stride ? stride : howmany));
00325       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00326       octave_idx_type dist = (stride == 1 ? npts : 1);
00327 
00328       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00329 
00330       for (octave_idx_type k = 0; k < nloop; k++)
00331         {
00332           for (octave_idx_type j = 0; j < howmany; j++)
00333             {
00334               octave_quit ();
00335 
00336               for (octave_idx_type l = 0; l < npts; l++)
00337                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00338 
00339               F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
00340 
00341               for (octave_idx_type l = 0; l < npts; l++)
00342                 retval ((l + k*npts)*stride + j*dist) = prow[l];
00343             }
00344         }
00345 
00346       stride *= dv2(i);
00347     }
00348 
00349   return retval;
00350 }
00351 
00352 FloatComplexNDArray
00353 FloatNDArray::ifourier2d (void) const
00354 {
00355   dim_vector dv = dims();
00356   dim_vector dv2 (dv(0), dv(1));
00357   int rank = 2;
00358   FloatComplexNDArray retval (*this);
00359   octave_idx_type stride = 1;
00360 
00361   for (int i = 0; i < rank; i++)
00362     {
00363       octave_idx_type npts = dv2(i);
00364       octave_idx_type nn = 4*npts+15;
00365       Array<FloatComplex> wsave (nn);
00366       FloatComplex *pwsave = wsave.fortran_vec ();
00367       Array<FloatComplex> row (npts);
00368       FloatComplex *prow = row.fortran_vec ();
00369 
00370       octave_idx_type howmany = numel () / npts;
00371       howmany = (stride == 1 ? howmany :
00372                  (howmany > stride ? stride : howmany));
00373       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00374       octave_idx_type dist = (stride == 1 ? npts : 1);
00375 
00376       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00377 
00378       for (octave_idx_type k = 0; k < nloop; k++)
00379         {
00380           for (octave_idx_type j = 0; j < howmany; j++)
00381             {
00382               octave_quit ();
00383 
00384               for (octave_idx_type l = 0; l < npts; l++)
00385                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00386 
00387               F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
00388 
00389               for (octave_idx_type l = 0; l < npts; l++)
00390                 retval ((l + k*npts)*stride + j*dist) = prow[l] /
00391                   static_cast<float> (npts);
00392             }
00393         }
00394 
00395       stride *= dv2(i);
00396     }
00397 
00398   return retval;
00399 }
00400 
00401 FloatComplexNDArray
00402 FloatNDArray::fourierNd (void) const
00403 {
00404   dim_vector dv = dims ();
00405   int rank = dv.length ();
00406   FloatComplexNDArray retval (*this);
00407   octave_idx_type stride = 1;
00408 
00409   for (int i = 0; i < rank; i++)
00410     {
00411       octave_idx_type npts = dv(i);
00412       octave_idx_type nn = 4*npts+15;
00413       Array<FloatComplex> wsave (nn);
00414       FloatComplex *pwsave = wsave.fortran_vec ();
00415       Array<FloatComplex> row (npts);
00416       FloatComplex *prow = row.fortran_vec ();
00417 
00418       octave_idx_type howmany = numel () / npts;
00419       howmany = (stride == 1 ? howmany :
00420                  (howmany > stride ? stride : howmany));
00421       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00422       octave_idx_type dist = (stride == 1 ? npts : 1);
00423 
00424       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00425 
00426       for (octave_idx_type k = 0; k < nloop; k++)
00427         {
00428           for (octave_idx_type j = 0; j < howmany; j++)
00429             {
00430               octave_quit ();
00431 
00432               for (octave_idx_type l = 0; l < npts; l++)
00433                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00434 
00435               F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
00436 
00437               for (octave_idx_type l = 0; l < npts; l++)
00438                 retval ((l + k*npts)*stride + j*dist) = prow[l];
00439             }
00440         }
00441 
00442       stride *= dv(i);
00443     }
00444 
00445   return retval;
00446 }
00447 
00448 FloatComplexNDArray
00449 FloatNDArray::ifourierNd (void) const
00450 {
00451   dim_vector dv = dims ();
00452   int rank = dv.length ();
00453   FloatComplexNDArray retval (*this);
00454   octave_idx_type stride = 1;
00455 
00456   for (int i = 0; i < rank; i++)
00457     {
00458       octave_idx_type npts = dv(i);
00459       octave_idx_type nn = 4*npts+15;
00460       Array<FloatComplex> wsave (nn);
00461       FloatComplex *pwsave = wsave.fortran_vec ();
00462       Array<FloatComplex> row (npts);
00463       FloatComplex *prow = row.fortran_vec ();
00464 
00465       octave_idx_type howmany = numel () / npts;
00466       howmany = (stride == 1 ? howmany :
00467                  (howmany > stride ? stride : howmany));
00468       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00469       octave_idx_type dist = (stride == 1 ? npts : 1);
00470 
00471       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00472 
00473       for (octave_idx_type k = 0; k < nloop; k++)
00474         {
00475           for (octave_idx_type j = 0; j < howmany; j++)
00476             {
00477               octave_quit ();
00478 
00479               for (octave_idx_type l = 0; l < npts; l++)
00480                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00481 
00482               F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
00483 
00484               for (octave_idx_type l = 0; l < npts; l++)
00485                 retval ((l + k*npts)*stride + j*dist) = prow[l] /
00486                   static_cast<float> (npts);
00487             }
00488         }
00489 
00490       stride *= dv(i);
00491     }
00492 
00493   return retval;
00494 }
00495 
00496 #endif
00497 
00498 // unary operations
00499 
00500 boolNDArray
00501 FloatNDArray::operator ! (void) const
00502 {
00503   if (any_element_is_nan ())
00504     gripe_nan_to_logical_conversion ();
00505 
00506   return do_mx_unary_op<bool, float> (*this, mx_inline_not);
00507 }
00508 
00509 bool
00510 FloatNDArray::any_element_is_negative (bool neg_zero) const
00511 {
00512   return (neg_zero ? test_all (xnegative_sign)
00513           : do_mx_check<float> (*this, mx_inline_any_negative));
00514 }
00515 
00516 bool
00517 FloatNDArray::any_element_is_positive (bool neg_zero) const
00518 {
00519   return (neg_zero ? test_all (xpositive_sign)
00520           : do_mx_check<float> (*this, mx_inline_any_positive));
00521 }
00522 
00523 bool
00524 FloatNDArray::any_element_is_nan (void) const
00525 {
00526   return do_mx_check<float> (*this, mx_inline_any_nan);
00527 }
00528 
00529 bool
00530 FloatNDArray::any_element_is_inf_or_nan (void) const
00531 {
00532   return ! do_mx_check<float> (*this, mx_inline_all_finite);
00533 }
00534 
00535 bool
00536 FloatNDArray::any_element_not_one_or_zero (void) const
00537 {
00538   return ! test_all (xis_one_or_zero);
00539 }
00540 
00541 bool
00542 FloatNDArray::all_elements_are_zero (void) const
00543 {
00544   return test_all (xis_zero);
00545 }
00546 
00547 bool
00548 FloatNDArray::all_elements_are_int_or_inf_or_nan (void) const
00549 {
00550   return test_all (xis_int_or_inf_or_nan);
00551 }
00552 
00553 // Return nonzero if any element of M is not an integer.  Also extract
00554 // the largest and smallest values and return them in MAX_VAL and MIN_VAL.
00555 
00556 bool
00557 FloatNDArray::all_integers (float& max_val, float& min_val) const
00558 {
00559   octave_idx_type nel = nelem ();
00560 
00561   if (nel > 0)
00562     {
00563       max_val = elem (0);
00564       min_val = elem (0);
00565     }
00566   else
00567     return false;
00568 
00569   for (octave_idx_type i = 0; i < nel; i++)
00570     {
00571       float val = elem (i);
00572 
00573       if (val > max_val)
00574         max_val = val;
00575 
00576       if (val < min_val)
00577         min_val = val;
00578 
00579       if (! xisinteger (val))
00580         return false;
00581     }
00582 
00583   return true;
00584 }
00585 
00586 bool
00587 FloatNDArray::all_integers (void) const
00588 {
00589   return test_all (xisinteger);
00590 }
00591 
00592 bool
00593 FloatNDArray::too_large_for_float (void) const
00594 {
00595   return false;
00596 }
00597 
00598 // FIXME -- this is not quite the right thing.
00599 
00600 boolNDArray
00601 FloatNDArray::all (int dim) const
00602 {
00603   return do_mx_red_op<bool, float> (*this, dim, mx_inline_all);
00604 }
00605 
00606 boolNDArray
00607 FloatNDArray::any (int dim) const
00608 {
00609   return do_mx_red_op<bool, float> (*this, dim, mx_inline_any);
00610 }
00611 
00612 FloatNDArray
00613 FloatNDArray::cumprod (int dim) const
00614 {
00615   return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumprod);
00616 }
00617 
00618 FloatNDArray
00619 FloatNDArray::cumsum (int dim) const
00620 {
00621   return do_mx_cum_op<float, float> (*this, dim, mx_inline_cumsum);
00622 }
00623 
00624 FloatNDArray
00625 FloatNDArray::prod (int dim) const
00626 {
00627   return do_mx_red_op<float, float> (*this, dim, mx_inline_prod);
00628 }
00629 
00630 FloatNDArray
00631 FloatNDArray::sum (int dim) const
00632 {
00633   return do_mx_red_op<float, float> (*this, dim, mx_inline_sum);
00634 }
00635 
00636 NDArray
00637 FloatNDArray::dsum (int dim) const
00638 {
00639   return do_mx_red_op<double, float> (*this, dim, mx_inline_dsum);
00640 }
00641 
00642 FloatNDArray
00643 FloatNDArray::sumsq (int dim) const
00644 {
00645   return do_mx_red_op<float, float> (*this, dim, mx_inline_sumsq);
00646 }
00647 
00648 FloatNDArray
00649 FloatNDArray::max (int dim) const
00650 {
00651   return do_mx_minmax_op<float> (*this, dim, mx_inline_max);
00652 }
00653 
00654 FloatNDArray
00655 FloatNDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
00656 {
00657   return do_mx_minmax_op<float> (*this, idx_arg, dim, mx_inline_max);
00658 }
00659 
00660 FloatNDArray
00661 FloatNDArray::min (int dim) const
00662 {
00663   return do_mx_minmax_op<float> (*this, dim, mx_inline_min);
00664 }
00665 
00666 FloatNDArray
00667 FloatNDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
00668 {
00669   return do_mx_minmax_op<float> (*this, idx_arg, dim, mx_inline_min);
00670 }
00671 
00672 FloatNDArray
00673 FloatNDArray::cummax (int dim) const
00674 {
00675   return do_mx_cumminmax_op<float> (*this, dim, mx_inline_cummax);
00676 }
00677 
00678 FloatNDArray
00679 FloatNDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
00680 {
00681   return do_mx_cumminmax_op<float> (*this, idx_arg, dim, mx_inline_cummax);
00682 }
00683 
00684 FloatNDArray
00685 FloatNDArray::cummin (int dim) const
00686 {
00687   return do_mx_cumminmax_op<float> (*this, dim, mx_inline_cummin);
00688 }
00689 
00690 FloatNDArray
00691 FloatNDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
00692 {
00693   return do_mx_cumminmax_op<float> (*this, idx_arg, dim, mx_inline_cummin);
00694 }
00695 
00696 FloatNDArray
00697 FloatNDArray::diff (octave_idx_type order, int dim) const
00698 {
00699   return do_mx_diff_op<float> (*this, dim, order, mx_inline_diff);
00700 }
00701 
00702 FloatNDArray
00703 FloatNDArray::concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx)
00704 {
00705   if (rb.numel () > 0)
00706     insert (rb, ra_idx);
00707   return *this;
00708 }
00709 
00710 FloatComplexNDArray
00711 FloatNDArray::concat (const FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
00712 {
00713   FloatComplexNDArray retval (*this);
00714   if (rb.numel () > 0)
00715     retval.insert (rb, ra_idx);
00716   return retval;
00717 }
00718 
00719 charNDArray
00720 FloatNDArray::concat (const charNDArray& rb, const Array<octave_idx_type>& ra_idx)
00721 {
00722   charNDArray retval (dims ());
00723   octave_idx_type nel = numel ();
00724 
00725   for (octave_idx_type i = 0; i < nel; i++)
00726     {
00727       float d = elem (i);
00728 
00729       if (xisnan (d))
00730         {
00731           (*current_liboctave_error_handler)
00732             ("invalid conversion from NaN to character");
00733           return retval;
00734         }
00735       else
00736         {
00737           octave_idx_type ival = NINTbig (d);
00738 
00739           if (ival < 0 || ival > UCHAR_MAX)
00740             // FIXME -- is there something
00741             // better we could do? Should we warn the user?
00742             ival = 0;
00743 
00744           retval.elem (i) = static_cast<char>(ival);
00745         }
00746     }
00747 
00748   if (rb.numel () == 0)
00749     return retval;
00750 
00751   retval.insert (rb, ra_idx);
00752   return retval;
00753 }
00754 
00755 FloatNDArray
00756 real (const FloatComplexNDArray& a)
00757 {
00758   return do_mx_unary_op<float, FloatComplex> (a, mx_inline_real);
00759 }
00760 
00761 FloatNDArray
00762 imag (const FloatComplexNDArray& a)
00763 {
00764   return do_mx_unary_op<float, FloatComplex> (a, mx_inline_imag);
00765 }
00766 
00767 FloatNDArray&
00768 FloatNDArray::insert (const FloatNDArray& a, octave_idx_type r, octave_idx_type c)
00769 {
00770   Array<float>::insert (a, r, c);
00771   return *this;
00772 }
00773 
00774 FloatNDArray&
00775 FloatNDArray::insert (const FloatNDArray& a, const Array<octave_idx_type>& ra_idx)
00776 {
00777   Array<float>::insert (a, ra_idx);
00778   return *this;
00779 }
00780 
00781 FloatNDArray
00782 FloatNDArray::abs (void) const
00783 {
00784   return do_mx_unary_map<float, float, std::abs> (*this);
00785 }
00786 
00787 boolNDArray
00788 FloatNDArray::isnan (void) const
00789 {
00790   return do_mx_unary_map<bool, float, xisnan> (*this);
00791 }
00792 
00793 boolNDArray
00794 FloatNDArray::isinf (void) const
00795 {
00796   return do_mx_unary_map<bool, float, xisinf> (*this);
00797 }
00798 
00799 boolNDArray
00800 FloatNDArray::isfinite (void) const
00801 {
00802   return do_mx_unary_map<bool, float, xfinite> (*this);
00803 }
00804 
00805 FloatMatrix
00806 FloatNDArray::matrix_value (void) const
00807 {
00808   FloatMatrix retval;
00809 
00810   if (ndims () == 2)
00811       retval = FloatMatrix (Array<float> (*this));
00812   else
00813     (*current_liboctave_error_handler)
00814       ("invalid conversion of FloatNDArray to FloatMatrix");
00815 
00816   return retval;
00817 }
00818 
00819 void
00820 FloatNDArray::increment_index (Array<octave_idx_type>& ra_idx,
00821                           const dim_vector& dimensions,
00822                           int start_dimension)
00823 {
00824   ::increment_index (ra_idx, dimensions, start_dimension);
00825 }
00826 
00827 octave_idx_type
00828 FloatNDArray::compute_index (Array<octave_idx_type>& ra_idx,
00829                         const dim_vector& dimensions)
00830 {
00831   return ::compute_index (ra_idx, dimensions);
00832 }
00833 
00834 FloatNDArray
00835 FloatNDArray::diag (octave_idx_type k) const
00836 {
00837   return MArray<float>::diag (k);
00838 }
00839 
00840 // This contains no information on the array structure !!!
00841 std::ostream&
00842 operator << (std::ostream& os, const FloatNDArray& a)
00843 {
00844   octave_idx_type nel = a.nelem ();
00845 
00846   for (octave_idx_type i = 0; i < nel; i++)
00847     {
00848       os << " ";
00849       octave_write_float (os, a.elem (i));
00850       os << "\n";
00851     }
00852   return os;
00853 }
00854 
00855 std::istream&
00856 operator >> (std::istream& is, FloatNDArray& a)
00857 {
00858   octave_idx_type nel = a.nelem ();
00859 
00860   if (nel > 0)
00861     {
00862       float tmp;
00863       for (octave_idx_type i = 0; i < nel; i++)
00864           {
00865             tmp = octave_read_value<float> (is);
00866             if (is)
00867               a.elem (i) = tmp;
00868             else
00869               goto done;
00870           }
00871     }
00872 
00873  done:
00874 
00875   return is;
00876 }
00877 
00878 MINMAX_FCNS (FloatNDArray, float)
00879 
00880 NDS_CMP_OPS (FloatNDArray, float)
00881 NDS_BOOL_OPS (FloatNDArray, float)
00882 
00883 SND_CMP_OPS (float, FloatNDArray)
00884 SND_BOOL_OPS (float, FloatNDArray)
00885 
00886 NDND_CMP_OPS (FloatNDArray, FloatNDArray)
00887 NDND_BOOL_OPS (FloatNDArray, FloatNDArray)
00888 
00889 BSXFUN_STDOP_DEFS_MXLOOP (FloatNDArray)
00890 BSXFUN_STDREL_DEFS_MXLOOP (FloatNDArray)
00891 
00892 BSXFUN_OP_DEF_MXLOOP (pow, FloatNDArray, mx_inline_pow)
00893 BSXFUN_OP2_DEF_MXLOOP (pow, FloatComplexNDArray, FloatComplexNDArray,
00894                        FloatNDArray, mx_inline_pow)
00895 BSXFUN_OP2_DEF_MXLOOP (pow, FloatComplexNDArray, FloatNDArray,
00896                        FloatComplexNDArray, mx_inline_pow)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines