fCNDArray.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 "fCNDArray.h"
00036 #include "functor.h"
00037 #include "lo-ieee.h"
00038 #include "lo-mappers.h"
00039 #include "MArray-defs.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 FloatComplexNDArray::FloatComplexNDArray (const charNDArray& a)
00048   : MArray<FloatComplex> (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 FloatComplexNDArray::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 FloatComplex *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 FloatComplexNDArray::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   const FloatComplex *in (fortran_vec ());
00108   FloatComplexNDArray retval (dv);
00109   FloatComplex *out (retval.fortran_vec ());
00110 
00111   // Need to be careful here about the distance between fft's
00112   for (octave_idx_type k = 0; k < nloop; k++)
00113     octave_fftw::ifft (in + k * stride * n, out + k * stride * n,
00114                       n, howmany, stride, dist);
00115 
00116   return retval;
00117 }
00118 
00119 FloatComplexNDArray
00120 FloatComplexNDArray::fourier2d (void) const
00121 {
00122   dim_vector dv = dims();
00123   if (dv.length () < 2)
00124     return FloatComplexNDArray ();
00125 
00126   dim_vector dv2(dv(0), dv(1));
00127   const FloatComplex *in = fortran_vec ();
00128   FloatComplexNDArray retval (dv);
00129   FloatComplex *out = retval.fortran_vec ();
00130   octave_idx_type howmany = numel() / dv(0) / dv(1);
00131   octave_idx_type dist = dv(0) * dv(1);
00132 
00133   for (octave_idx_type i=0; i < howmany; i++)
00134     octave_fftw::fftNd (in + i*dist, out + i*dist, 2, dv2);
00135 
00136   return retval;
00137 }
00138 
00139 FloatComplexNDArray
00140 FloatComplexNDArray::ifourier2d (void) const
00141 {
00142   dim_vector dv = dims();
00143   if (dv.length () < 2)
00144     return FloatComplexNDArray ();
00145 
00146   dim_vector dv2(dv(0), dv(1));
00147   const FloatComplex *in = fortran_vec ();
00148   FloatComplexNDArray retval (dv);
00149   FloatComplex *out = retval.fortran_vec ();
00150   octave_idx_type howmany = numel() / dv(0) / dv(1);
00151   octave_idx_type dist = dv(0) * dv(1);
00152 
00153   for (octave_idx_type i=0; i < howmany; i++)
00154     octave_fftw::ifftNd (in + i*dist, out + i*dist, 2, dv2);
00155 
00156   return retval;
00157 }
00158 
00159 FloatComplexNDArray
00160 FloatComplexNDArray::fourierNd (void) const
00161 {
00162   dim_vector dv = dims ();
00163   int rank = dv.length ();
00164 
00165   const FloatComplex *in (fortran_vec ());
00166   FloatComplexNDArray retval (dv);
00167   FloatComplex *out (retval.fortran_vec ());
00168 
00169   octave_fftw::fftNd (in, out, rank, dv);
00170 
00171   return retval;
00172 }
00173 
00174 FloatComplexNDArray
00175 FloatComplexNDArray::ifourierNd (void) const
00176 {
00177   dim_vector dv = dims ();
00178   int rank = dv.length ();
00179 
00180   const FloatComplex *in (fortran_vec ());
00181   FloatComplexNDArray retval (dv);
00182   FloatComplex *out (retval.fortran_vec ());
00183 
00184   octave_fftw::ifftNd (in, out, rank, dv);
00185 
00186   return retval;
00187 }
00188 
00189 #else
00190 
00191 extern "C"
00192 {
00193   F77_RET_T
00194   F77_FUNC (cffti, CFFTI) (const octave_idx_type&, FloatComplex*);
00195 
00196   F77_RET_T
00197   F77_FUNC (cfftf, CFFTF) (const octave_idx_type&, FloatComplex*,
00198                            FloatComplex*);
00199 
00200   F77_RET_T
00201   F77_FUNC (cfftb, CFFTB) (const octave_idx_type&, FloatComplex*,
00202                            FloatComplex*);
00203 }
00204 
00205 FloatComplexNDArray
00206 FloatComplexNDArray::fourier (int dim) const
00207 {
00208   dim_vector dv = dims ();
00209 
00210   if (dim > dv.length () || dim < 0)
00211     return FloatComplexNDArray ();
00212 
00213   FloatComplexNDArray retval (dv);
00214   octave_idx_type npts = dv(dim);
00215   octave_idx_type nn = 4*npts+15;
00216   Array<FloatComplex> wsave (nn, 1);
00217   FloatComplex *pwsave = wsave.fortran_vec ();
00218 
00219   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
00220 
00221   octave_idx_type stride = 1;
00222 
00223   for (int i = 0; i < dim; i++)
00224     stride *= dv(i);
00225 
00226   octave_idx_type howmany = numel () / npts;
00227   howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00228   octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00229   octave_idx_type dist = (stride == 1 ? npts : 1);
00230 
00231   F77_FUNC (cffti, CFFTI) (npts, pwsave);
00232 
00233   for (octave_idx_type k = 0; k < nloop; k++)
00234     {
00235       for (octave_idx_type j = 0; j < howmany; j++)
00236         {
00237           octave_quit ();
00238 
00239           for (octave_idx_type i = 0; i < npts; i++)
00240             tmp[i] = elem((i + k*npts)*stride + j*dist);
00241 
00242           F77_FUNC (cfftf, CFFTF) (npts, tmp, pwsave);
00243 
00244           for (octave_idx_type i = 0; i < npts; i++)
00245             retval ((i + k*npts)*stride + j*dist) = tmp[i];
00246         }
00247     }
00248 
00249   return retval;
00250 }
00251 
00252 FloatComplexNDArray
00253 FloatComplexNDArray::ifourier (int dim) const
00254 {
00255   dim_vector dv = dims ();
00256 
00257   if (dim > dv.length () || dim < 0)
00258     return FloatComplexNDArray ();
00259 
00260   FloatComplexNDArray retval (dv);
00261   octave_idx_type npts = dv(dim);
00262   octave_idx_type nn = 4*npts+15;
00263   Array<FloatComplex> wsave (nn, 1);
00264   FloatComplex *pwsave = wsave.fortran_vec ();
00265 
00266   OCTAVE_LOCAL_BUFFER (FloatComplex, tmp, npts);
00267 
00268   octave_idx_type stride = 1;
00269 
00270   for (int i = 0; i < dim; i++)
00271     stride *= dv(i);
00272 
00273   octave_idx_type howmany = numel () / npts;
00274   howmany = (stride == 1 ? howmany : (howmany > stride ? stride : howmany));
00275   octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00276   octave_idx_type dist = (stride == 1 ? npts : 1);
00277 
00278   F77_FUNC (cffti, CFFTI) (npts, pwsave);
00279 
00280   for (octave_idx_type k = 0; k < nloop; k++)
00281     {
00282       for (octave_idx_type j = 0; j < howmany; j++)
00283         {
00284           octave_quit ();
00285 
00286           for (octave_idx_type i = 0; i < npts; i++)
00287             tmp[i] = elem((i + k*npts)*stride + j*dist);
00288 
00289           F77_FUNC (cfftb, CFFTB) (npts, tmp, pwsave);
00290 
00291           for (octave_idx_type i = 0; i < npts; i++)
00292             retval ((i + k*npts)*stride + j*dist) = tmp[i] /
00293               static_cast<float> (npts);
00294         }
00295     }
00296 
00297   return retval;
00298 }
00299 
00300 FloatComplexNDArray
00301 FloatComplexNDArray::fourier2d (void) const
00302 {
00303   dim_vector dv = dims ();
00304   dim_vector dv2 (dv(0), dv(1));
00305   int rank = 2;
00306   FloatComplexNDArray retval (*this);
00307   octave_idx_type stride = 1;
00308 
00309   for (int i = 0; i < rank; i++)
00310     {
00311       octave_idx_type npts = dv2(i);
00312       octave_idx_type nn = 4*npts+15;
00313       Array<FloatComplex> wsave (nn, 1);
00314       FloatComplex *pwsave = wsave.fortran_vec ();
00315       Array<FloatComplex> row (npts, 1);
00316       FloatComplex *prow = row.fortran_vec ();
00317 
00318       octave_idx_type howmany = numel () / npts;
00319       howmany = (stride == 1 ? howmany :
00320                  (howmany > stride ? stride : howmany));
00321       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00322       octave_idx_type dist = (stride == 1 ? npts : 1);
00323 
00324       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00325 
00326       for (octave_idx_type k = 0; k < nloop; k++)
00327         {
00328           for (octave_idx_type j = 0; j < howmany; j++)
00329             {
00330               octave_quit ();
00331 
00332               for (octave_idx_type l = 0; l < npts; l++)
00333                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00334 
00335               F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
00336 
00337               for (octave_idx_type l = 0; l < npts; l++)
00338                 retval ((l + k*npts)*stride + j*dist) = prow[l];
00339             }
00340         }
00341 
00342       stride *= dv2(i);
00343     }
00344 
00345   return retval;
00346 }
00347 
00348 FloatComplexNDArray
00349 FloatComplexNDArray::ifourier2d (void) const
00350 {
00351   dim_vector dv = dims();
00352   dim_vector dv2 (dv(0), dv(1));
00353   int rank = 2;
00354   FloatComplexNDArray retval (*this);
00355   octave_idx_type stride = 1;
00356 
00357   for (int i = 0; i < rank; i++)
00358     {
00359       octave_idx_type npts = dv2(i);
00360       octave_idx_type nn = 4*npts+15;
00361       Array<FloatComplex> wsave (nn, 1);
00362       FloatComplex *pwsave = wsave.fortran_vec ();
00363       Array<FloatComplex> row (npts, 1);
00364       FloatComplex *prow = row.fortran_vec ();
00365 
00366       octave_idx_type howmany = numel () / npts;
00367       howmany = (stride == 1 ? howmany :
00368                  (howmany > stride ? stride : howmany));
00369       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00370       octave_idx_type dist = (stride == 1 ? npts : 1);
00371 
00372       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00373 
00374       for (octave_idx_type k = 0; k < nloop; k++)
00375         {
00376           for (octave_idx_type j = 0; j < howmany; j++)
00377             {
00378               octave_quit ();
00379 
00380               for (octave_idx_type l = 0; l < npts; l++)
00381                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00382 
00383               F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
00384 
00385               for (octave_idx_type l = 0; l < npts; l++)
00386                 retval ((l + k*npts)*stride + j*dist) = prow[l] /
00387                   static_cast<float> (npts);
00388             }
00389         }
00390 
00391       stride *= dv2(i);
00392     }
00393 
00394   return retval;
00395 }
00396 
00397 FloatComplexNDArray
00398 FloatComplexNDArray::fourierNd (void) const
00399 {
00400   dim_vector dv = dims ();
00401   int rank = dv.length ();
00402   FloatComplexNDArray retval (*this);
00403   octave_idx_type stride = 1;
00404 
00405   for (int i = 0; i < rank; i++)
00406     {
00407       octave_idx_type npts = dv(i);
00408       octave_idx_type nn = 4*npts+15;
00409       Array<FloatComplex> wsave (nn, 1);
00410       FloatComplex *pwsave = wsave.fortran_vec ();
00411       Array<FloatComplex> row (npts, 1);
00412       FloatComplex *prow = row.fortran_vec ();
00413 
00414       octave_idx_type howmany = numel () / npts;
00415       howmany = (stride == 1 ? howmany :
00416                  (howmany > stride ? stride : howmany));
00417       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00418       octave_idx_type dist = (stride == 1 ? npts : 1);
00419 
00420       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00421 
00422       for (octave_idx_type k = 0; k < nloop; k++)
00423         {
00424           for (octave_idx_type j = 0; j < howmany; j++)
00425             {
00426               octave_quit ();
00427 
00428               for (octave_idx_type l = 0; l < npts; l++)
00429                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00430 
00431               F77_FUNC (cfftf, CFFTF) (npts, prow, pwsave);
00432 
00433               for (octave_idx_type l = 0; l < npts; l++)
00434                 retval ((l + k*npts)*stride + j*dist) = prow[l];
00435             }
00436         }
00437 
00438       stride *= dv(i);
00439     }
00440 
00441   return retval;
00442 }
00443 
00444 FloatComplexNDArray
00445 FloatComplexNDArray::ifourierNd (void) const
00446 {
00447   dim_vector dv = dims ();
00448   int rank = dv.length ();
00449   FloatComplexNDArray retval (*this);
00450   octave_idx_type stride = 1;
00451 
00452   for (int i = 0; i < rank; i++)
00453     {
00454       octave_idx_type npts = dv(i);
00455       octave_idx_type nn = 4*npts+15;
00456       Array<FloatComplex> wsave (nn, 1);
00457       FloatComplex *pwsave = wsave.fortran_vec ();
00458       Array<FloatComplex> row (npts, 1);
00459       FloatComplex *prow = row.fortran_vec ();
00460 
00461       octave_idx_type howmany = numel () / npts;
00462       howmany = (stride == 1 ? howmany :
00463                  (howmany > stride ? stride : howmany));
00464       octave_idx_type nloop = (stride == 1 ? 1 : numel () / npts / stride);
00465       octave_idx_type dist = (stride == 1 ? npts : 1);
00466 
00467       F77_FUNC (cffti, CFFTI) (npts, pwsave);
00468 
00469       for (octave_idx_type k = 0; k < nloop; k++)
00470         {
00471           for (octave_idx_type j = 0; j < howmany; j++)
00472             {
00473               octave_quit ();
00474 
00475               for (octave_idx_type l = 0; l < npts; l++)
00476                 prow[l] = retval ((l + k*npts)*stride + j*dist);
00477 
00478               F77_FUNC (cfftb, CFFTB) (npts, prow, pwsave);
00479 
00480               for (octave_idx_type l = 0; l < npts; l++)
00481                 retval ((l + k*npts)*stride + j*dist) = prow[l] /
00482                   static_cast<float> (npts);
00483             }
00484         }
00485 
00486       stride *= dv(i);
00487     }
00488 
00489   return retval;
00490 }
00491 
00492 #endif
00493 
00494 // unary operations
00495 
00496 boolNDArray
00497 FloatComplexNDArray::operator ! (void) const
00498 {
00499   if (any_element_is_nan ())
00500     gripe_nan_to_logical_conversion ();
00501 
00502   return do_mx_unary_op<bool, FloatComplex> (*this, mx_inline_not);
00503 }
00504 
00505 // FIXME -- this is not quite the right thing.
00506 
00507 bool
00508 FloatComplexNDArray::any_element_is_nan (void) const
00509 {
00510   return do_mx_check<FloatComplex> (*this, mx_inline_any_nan);
00511 }
00512 
00513 bool
00514 FloatComplexNDArray::any_element_is_inf_or_nan (void) const
00515 {
00516   return ! do_mx_check<FloatComplex> (*this, mx_inline_all_finite);
00517 }
00518 
00519 // Return true if no elements have imaginary components.
00520 
00521 bool
00522 FloatComplexNDArray::all_elements_are_real (void) const
00523 {
00524   return do_mx_check<FloatComplex> (*this, mx_inline_all_real);
00525 }
00526 
00527 // Return nonzero if any element of CM has a non-integer real or
00528 // imaginary part.  Also extract the largest and smallest (real or
00529 // imaginary) values and return them in MAX_VAL and MIN_VAL.
00530 
00531 bool
00532 FloatComplexNDArray::all_integers (float& max_val, float& min_val) const
00533 {
00534   octave_idx_type nel = nelem ();
00535 
00536   if (nel > 0)
00537     {
00538       FloatComplex val = elem (0);
00539 
00540       float r_val = std::real (val);
00541       float i_val = std::imag (val);
00542 
00543       max_val = r_val;
00544       min_val = r_val;
00545 
00546       if (i_val > max_val)
00547         max_val = i_val;
00548 
00549       if (i_val < max_val)
00550         min_val = i_val;
00551     }
00552   else
00553     return false;
00554 
00555   for (octave_idx_type i = 0; i < nel; i++)
00556     {
00557       FloatComplex val = elem (i);
00558 
00559       float r_val = std::real (val);
00560       float i_val = std::imag (val);
00561 
00562       if (r_val > max_val)
00563         max_val = r_val;
00564 
00565       if (i_val > max_val)
00566         max_val = i_val;
00567 
00568       if (r_val < min_val)
00569         min_val = r_val;
00570 
00571       if (i_val < min_val)
00572         min_val = i_val;
00573 
00574       if (D_NINT (r_val) != r_val || D_NINT (i_val) != i_val)
00575         return false;
00576     }
00577 
00578   return true;
00579 }
00580 
00581 bool
00582 FloatComplexNDArray::too_large_for_float (void) const
00583 {
00584   octave_idx_type nel = nelem ();
00585 
00586   for (octave_idx_type i = 0; i < nel; i++)
00587     {
00588       FloatComplex val = elem (i);
00589 
00590       float r_val = std::real (val);
00591       float i_val = std::imag (val);
00592 
00593       if ((! (xisnan (r_val) || xisinf (r_val))
00594            && fabs (r_val) > FLT_MAX)
00595           || (! (xisnan (i_val) || xisinf (i_val))
00596               && fabs (i_val) > FLT_MAX))
00597         return true;
00598     }
00599 
00600   return false;
00601 }
00602 
00603 boolNDArray
00604 FloatComplexNDArray::all (int dim) const
00605 {
00606   return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_all);
00607 }
00608 
00609 boolNDArray
00610 FloatComplexNDArray::any (int dim) const
00611 {
00612   return do_mx_red_op<bool, FloatComplex> (*this, dim, mx_inline_any);
00613 }
00614 
00615 FloatComplexNDArray
00616 FloatComplexNDArray::cumprod (int dim) const
00617 {
00618   return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_cumprod);
00619 }
00620 
00621 FloatComplexNDArray
00622 FloatComplexNDArray::cumsum (int dim) const
00623 {
00624   return do_mx_cum_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_cumsum);
00625 }
00626 
00627 FloatComplexNDArray
00628 FloatComplexNDArray::prod (int dim) const
00629 {
00630   return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_prod);
00631 }
00632 
00633 FloatComplexNDArray
00634 FloatComplexNDArray::sum (int dim) const
00635 {
00636   return do_mx_red_op<FloatComplex, FloatComplex> (*this, dim, mx_inline_sum);
00637 }
00638 
00639 ComplexNDArray
00640 FloatComplexNDArray::dsum (int dim) const
00641 {
00642   return do_mx_red_op<Complex, FloatComplex> (*this, dim, mx_inline_dsum);
00643 }
00644 
00645 FloatComplexNDArray
00646 FloatComplexNDArray::sumsq (int dim) const
00647 {
00648   return do_mx_red_op<float, FloatComplex> (*this, dim, mx_inline_sumsq);
00649 }
00650 
00651 FloatComplexNDArray
00652 FloatComplexNDArray::diff (octave_idx_type order, int dim) const
00653 {
00654   return do_mx_diff_op<FloatComplex> (*this, dim, order, mx_inline_diff);
00655 }
00656 
00657 FloatComplexNDArray
00658 FloatComplexNDArray::concat (const FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
00659 {
00660   if (rb.numel () > 0)
00661     insert (rb, ra_idx);
00662   return *this;
00663 }
00664 
00665 FloatComplexNDArray
00666 FloatComplexNDArray::concat (const FloatNDArray& rb, const Array<octave_idx_type>& ra_idx)
00667 {
00668   FloatComplexNDArray tmp (rb);
00669   if (rb.numel () > 0)
00670     insert (tmp, ra_idx);
00671   return *this;
00672 }
00673 
00674 FloatComplexNDArray
00675 concat (NDArray& ra, FloatComplexNDArray& rb, const Array<octave_idx_type>& ra_idx)
00676 {
00677   FloatComplexNDArray retval (ra);
00678   if (rb.numel () > 0)
00679     retval.insert (rb, ra_idx);
00680   return retval;
00681 }
00682 
00683 static const FloatComplex FloatComplex_NaN_result (octave_Float_NaN, octave_Float_NaN);
00684 
00685 FloatComplexNDArray
00686 FloatComplexNDArray::max (int dim) const
00687 {
00688   return do_mx_minmax_op<FloatComplex> (*this, dim, mx_inline_max);
00689 }
00690 
00691 FloatComplexNDArray
00692 FloatComplexNDArray::max (Array<octave_idx_type>& idx_arg, int dim) const
00693 {
00694   return do_mx_minmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_max);
00695 }
00696 
00697 FloatComplexNDArray
00698 FloatComplexNDArray::min (int dim) const
00699 {
00700   return do_mx_minmax_op<FloatComplex> (*this, dim, mx_inline_min);
00701 }
00702 
00703 FloatComplexNDArray
00704 FloatComplexNDArray::min (Array<octave_idx_type>& idx_arg, int dim) const
00705 {
00706   return do_mx_minmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_min);
00707 }
00708 
00709 FloatComplexNDArray
00710 FloatComplexNDArray::cummax (int dim) const
00711 {
00712   return do_mx_cumminmax_op<FloatComplex> (*this, dim, mx_inline_cummax);
00713 }
00714 
00715 FloatComplexNDArray
00716 FloatComplexNDArray::cummax (Array<octave_idx_type>& idx_arg, int dim) const
00717 {
00718   return do_mx_cumminmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_cummax);
00719 }
00720 
00721 FloatComplexNDArray
00722 FloatComplexNDArray::cummin (int dim) const
00723 {
00724   return do_mx_cumminmax_op<FloatComplex> (*this, dim, mx_inline_cummin);
00725 }
00726 
00727 FloatComplexNDArray
00728 FloatComplexNDArray::cummin (Array<octave_idx_type>& idx_arg, int dim) const
00729 {
00730   return do_mx_cumminmax_op<FloatComplex> (*this, idx_arg, dim, mx_inline_cummin);
00731 }
00732 
00733 FloatNDArray
00734 FloatComplexNDArray::abs (void) const
00735 {
00736   return do_mx_unary_map<float, FloatComplex, std::abs> (*this);
00737 }
00738 
00739 boolNDArray
00740 FloatComplexNDArray::isnan (void) const
00741 {
00742   return do_mx_unary_map<bool, FloatComplex, xisnan> (*this);
00743 }
00744 
00745 boolNDArray
00746 FloatComplexNDArray::isinf (void) const
00747 {
00748   return do_mx_unary_map<bool, FloatComplex, xisinf> (*this);
00749 }
00750 
00751 boolNDArray
00752 FloatComplexNDArray::isfinite (void) const
00753 {
00754   return do_mx_unary_map<bool, FloatComplex, xfinite> (*this);
00755 }
00756 
00757 FloatComplexNDArray
00758 conj (const FloatComplexNDArray& a)
00759 {
00760   return do_mx_unary_map<FloatComplex, FloatComplex, std::conj<float> > (a);
00761 }
00762 
00763 FloatComplexNDArray&
00764 FloatComplexNDArray::insert (const NDArray& a, octave_idx_type r, octave_idx_type c)
00765 {
00766   dim_vector a_dv = a.dims ();
00767 
00768   int n = a_dv.length ();
00769 
00770   if (n == dimensions.length ())
00771     {
00772       Array<octave_idx_type> a_ra_idx (dim_vector (a_dv.length (), 1), 0);
00773 
00774       a_ra_idx.elem (0) = r;
00775       a_ra_idx.elem (1) = c;
00776 
00777       for (int i = 0; i < n; i++)
00778         {
00779           if (a_ra_idx (i) < 0 || (a_ra_idx (i) + a_dv (i)) > dimensions (i))
00780             {
00781               (*current_liboctave_error_handler)
00782                 ("Array<T>::insert: range error for insert");
00783               return *this;
00784             }
00785         }
00786 
00787       a_ra_idx.elem (0) = 0;
00788       a_ra_idx.elem (1) = 0;
00789 
00790       octave_idx_type n_elt = a.numel ();
00791 
00792       // IS make_unique () NECCESSARY HERE??
00793 
00794       for (octave_idx_type i = 0; i < n_elt; i++)
00795         {
00796           Array<octave_idx_type> ra_idx = a_ra_idx;
00797 
00798           ra_idx.elem (0) = a_ra_idx (0) + r;
00799           ra_idx.elem (1) = a_ra_idx (1) + c;
00800 
00801           elem (ra_idx) = a.elem (a_ra_idx);
00802 
00803           increment_index (a_ra_idx, a_dv);
00804         }
00805     }
00806   else
00807     (*current_liboctave_error_handler)
00808       ("Array<T>::insert: invalid indexing operation");
00809 
00810   return *this;
00811 }
00812 
00813 FloatComplexNDArray&
00814 FloatComplexNDArray::insert (const FloatComplexNDArray& a, octave_idx_type r, octave_idx_type c)
00815 {
00816   Array<FloatComplex>::insert (a, r, c);
00817   return *this;
00818 }
00819 
00820 FloatComplexNDArray&
00821 FloatComplexNDArray::insert (const FloatComplexNDArray& a, const Array<octave_idx_type>& ra_idx)
00822 {
00823   Array<FloatComplex>::insert (a, ra_idx);
00824   return *this;
00825 }
00826 
00827 FloatComplexMatrix
00828 FloatComplexNDArray::matrix_value (void) const
00829 {
00830   FloatComplexMatrix retval;
00831 
00832   if (ndims () == 2)
00833       retval = FloatComplexMatrix (Array<FloatComplex> (*this));
00834   else
00835     (*current_liboctave_error_handler)
00836       ("invalid conversion of FloatComplexNDArray to FloatComplexMatrix");
00837 
00838   return retval;
00839 }
00840 
00841 void
00842 FloatComplexNDArray::increment_index (Array<octave_idx_type>& ra_idx,
00843                                  const dim_vector& dimensions,
00844                                  int start_dimension)
00845 {
00846   ::increment_index (ra_idx, dimensions, start_dimension);
00847 }
00848 
00849 octave_idx_type
00850 FloatComplexNDArray::compute_index (Array<octave_idx_type>& ra_idx,
00851                                const dim_vector& dimensions)
00852 {
00853   return ::compute_index (ra_idx, dimensions);
00854 }
00855 
00856 FloatComplexNDArray
00857 FloatComplexNDArray::diag (octave_idx_type k) const
00858 {
00859   return MArray<FloatComplex>::diag (k);
00860 }
00861 
00862 // This contains no information on the array structure !!!
00863 std::ostream&
00864 operator << (std::ostream& os, const FloatComplexNDArray& a)
00865 {
00866   octave_idx_type nel = a.nelem ();
00867 
00868   for (octave_idx_type i = 0; i < nel; i++)
00869     {
00870       os << " ";
00871       octave_write_complex (os, a.elem (i));
00872       os << "\n";
00873     }
00874   return os;
00875 }
00876 
00877 std::istream&
00878 operator >> (std::istream& is, FloatComplexNDArray& a)
00879 {
00880   octave_idx_type nel = a.nelem ();
00881 
00882   if (nel > 0)
00883     {
00884       FloatComplex tmp;
00885       for (octave_idx_type i = 0; i < nel; i++)
00886           {
00887             tmp = octave_read_value<FloatComplex> (is);
00888             if (is)
00889               a.elem (i) = tmp;
00890             else
00891               goto done;
00892           }
00893     }
00894 
00895  done:
00896 
00897   return is;
00898 }
00899 
00900 MINMAX_FCNS (FloatComplexNDArray, FloatComplex)
00901 
00902 NDS_CMP_OPS (FloatComplexNDArray, FloatComplex)
00903 NDS_BOOL_OPS (FloatComplexNDArray, FloatComplex)
00904 
00905 SND_CMP_OPS (FloatComplex, FloatComplexNDArray)
00906 SND_BOOL_OPS (FloatComplex, FloatComplexNDArray)
00907 
00908 NDND_CMP_OPS (FloatComplexNDArray, FloatComplexNDArray)
00909 NDND_BOOL_OPS (FloatComplexNDArray, FloatComplexNDArray)
00910 
00911 FloatComplexNDArray& operator *= (FloatComplexNDArray& a, float s)
00912 {
00913   if (a.is_shared ())
00914     a = a * s;
00915   else
00916     do_ms_inplace_op<FloatComplex, float> (a, s, mx_inline_mul2);
00917   return a;
00918 }
00919 
00920 FloatComplexNDArray& operator /= (FloatComplexNDArray& a, float s)
00921 {
00922   if (a.is_shared ())
00923     a = a / s;
00924   else
00925     do_ms_inplace_op<FloatComplex, float> (a, s, mx_inline_div2);
00926   return a;
00927 }
00928 
00929 BSXFUN_STDOP_DEFS_MXLOOP (FloatComplexNDArray)
00930 BSXFUN_STDREL_DEFS_MXLOOP (FloatComplexNDArray)
00931 
00932 BSXFUN_OP_DEF_MXLOOP (pow, FloatComplexNDArray, mx_inline_pow)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines