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