pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_NumericalArray.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_NUMERICALARRAY_H
00040 #define PLONK_NUMERICALARRAY_H
00041 
00042 #include "../core/plonk_CoreForwardDeclarations.h"
00043 #include "plonk_ContainerForwardDeclarations.h"
00044 #include "plonk_DynamicContainer.h"
00045 
00046 #include "../maths/plonk_InlineUnaryOps.h"
00047 #include "../maths/plonk_InlineBinaryOps.h"
00048 #include "../maths/plonk_InlineMiscOps.h"
00049 #include "../random/plonk_RNG.h"
00050 #include "plonk_Int24.h"
00051 
00052     
00053 template<class NumericalType>
00054 class NumericalArrayFillerBase
00055 {
00056 public:
00057     static inline void fill (NumericalType* const dst, const NumericalType value, const UnsignedLong numItems) throw()
00058     {
00059         for (UnsignedLong i = 0; i < numItems; ++i)
00060             dst[i] = value;
00061     }
00062     
00063     static inline void line (NumericalType* const dst, const UnsignedLong size, const NumericalType start, const NumericalType end) throw()
00064         {
00065         if (size >= 2)
00066         {
00067             double inc = double (end - start) / (size - 1);
00068             double currentValue = start;
00069             
00070             for (int i = 0; i < size; ++i)
00071             {
00072                 NumericalConverter::roundCopy (currentValue, dst[i]);
00073                 currentValue += inc;
00074             }
00075                 }
00076         else plonk_assertfalse;
00077         }
00078         
00079         static inline void series (NumericalType* const dst,
00080                                const UnsignedLong size, 
00081                                const NumericalType start, 
00082                                const NumericalType grow) throw()
00083         {
00084         if (size >= 2)
00085         {                        
00086             NumericalType currentValue = start;
00087             
00088             for (UnsignedLong i = 0; i < size; ++i)
00089             {
00090                 dst[i] = currentValue;
00091                 currentValue += grow;
00092             }
00093                 }
00094         else plonk_assertfalse;
00095         }
00096         
00097         static inline void geom (NumericalType* const dst,
00098                              const UnsignedLong size, 
00099                              const NumericalType start, 
00100                              const NumericalType grow) throw()
00101         {
00102         if (size >= 2)
00103         {                        
00104             NumericalType currentValue = start;
00105             
00106             for (int i = 0; i < size; ++i)
00107             {
00108                 dst[i] = currentValue;
00109                 currentValue *= grow;
00110             }
00111                 }
00112         else plonk_assertfalse;
00113         }
00114         
00115         static inline void rand (NumericalType* const dst,
00116                              const UnsignedLong size, 
00117                              const NumericalType lower, 
00118                              const NumericalType upper) throw()
00119         {
00120         if (size >= 1)
00121         {                                    
00122             for (int i = 0; i < size; ++i)
00123                 dst[i] = plonk::rand (lower, upper);
00124                 }
00125         else plonk_assertfalse;
00126     }
00127     
00128     static inline void rand (NumericalType* const dst,
00129                              const UnsignedLong size, 
00130                              const NumericalType upper) throw()
00131     {
00132         return rand (dst, size, NumericalType (0), upper);
00133     }
00134         
00135         static inline void rand2 (NumericalType* const dst,
00136                               const UnsignedLong size, 
00137                               const NumericalType positive) throw()
00138         {
00139                 return rand (dst, size, -positive, positive);
00140         }
00141         
00142         static inline void exprand (NumericalType* const dst,
00143                                 const UnsignedLong size, 
00144                                 const NumericalType lower, 
00145                                 const NumericalType upper) throw()
00146         {
00147         if (size >= 1)
00148         {                                    
00149             for (int i = 0; i < size; ++i)
00150                 dst[i] = plonk::exprand (lower, upper);
00151                 }
00152         else plonk_assertfalse;
00153         }
00154 };
00155 
00156 template<class NumericalType>
00157 class NumericalArrayFiller : public NumericalArrayFillerBase<NumericalType>
00158 {
00159 };
00160 
00161 template<>
00162 class NumericalArrayFiller<float> : public NumericalArrayFillerBase<float>
00163 {
00164 public:
00165     static inline void fill (float* const dst, const float value, const UnsignedLong numItems) throw()
00166     {        
00167         pl_VectorFillF_N1 (dst, value, numItems);
00168     }
00169     
00170     static inline void line (float* const dst, const UnsignedLong size, const float start, const float end) throw()
00171         {
00172         if (size >= 2)
00173         {
00174             pl_VectorLineF_N11 (dst, start, end, size);
00175                 }
00176         else plonk_assertfalse;
00177         }
00178         
00179         static inline void series (float* const dst,
00180                                const UnsignedLong size, 
00181                                const float start, 
00182                                const float grow) throw()
00183         {
00184         if (size >= 2)
00185         {                        
00186             pl_VectorRampF_N11 (dst, start, grow, size);
00187                 }
00188         else plonk_assertfalse;
00189         }
00190 };
00191 
00192 template<>
00193 class NumericalArrayFiller<double> : public NumericalArrayFillerBase<double>
00194 {
00195 public:
00196     static inline void fill (double* const dst, const double value, const UnsignedLong numItems) throw()
00197     {        
00198         pl_VectorFillD_N1 (dst, value, numItems);
00199     }
00200     
00201     static inline void line (double* const dst, const UnsignedLong size, const double start, const double end) throw()
00202         {
00203         if (size >= 2)
00204         {
00205             pl_VectorLineD_N11 (dst, start, end, size);
00206                 }
00207         else plonk_assertfalse;
00208         }
00209         
00210         static inline void series (double* const dst,
00211                                const UnsignedLong size, 
00212                                const double start, 
00213                                const double grow) throw()
00214         {
00215         if (size >= 2)
00216         {                        
00217             pl_VectorRampD_N11 (dst, start, grow, size);
00218                 }
00219         else plonk_assertfalse;
00220         }
00221 };
00222 
00223 
00224 template<class NumericalType, class OtherType>
00225 class NumericalArrayConverterBase
00226 {
00227 public:
00228     static inline void convertDirect (NumericalType* const dst, const OtherType* const src, const UnsignedLong numItems) throw()
00229     {
00230         for (UnsignedLong i = 0; i < numItems; ++i)
00231             NumericalConverter::roundCopy (src[i], dst[i]);
00232     }
00233     
00234     static inline void convertScaled (NumericalType* const dst, const OtherType* const src, const UnsignedLong numItems) throw()
00235     {
00236         typedef typename BinaryOpTypeUtility<NumericalType, OtherType>::CalcType CalcType;
00237         
00238         const CalcType typePeak (TypeUtility<NumericalType>::getTypePeak());
00239         const CalcType otherTypePeak (TypeUtility<OtherType>::getTypePeak());
00240         
00241                 UnsignedLong i;
00242         
00243         for (i = 0; i < numItems; ++i)
00244         {
00245             CalcType temp;
00246             NumericalConverter::roundCopy (src[i], temp);
00247             dst[i] = NumericalType (temp * typePeak / otherTypePeak);
00248         }
00249     }
00250 };
00251 
00252 template<class NumericalType>
00253 class NumericalArrayConverterCopy
00254 {
00255 public:
00256     static inline void convertDirect (NumericalType* const dst, const NumericalType* const src, const UnsignedLong numItems) throw()
00257     {
00258         NumericalArray<NumericalType>::copyData (dst, src, numItems);
00259     }
00260     
00261     static inline void convertScaled (NumericalType* const dst, const NumericalType* const src, const UnsignedLong numItems) throw()
00262     {
00263         NumericalArray<NumericalType>::copyData (dst, src, numItems);
00264     }        
00265 };
00266 
00267 template<>
00268 class NumericalArrayConverterBase<float, char>
00269 {
00270 public:
00271     static inline void convertDirect (float* const dst, const char* const src, const UnsignedLong numItems) throw()
00272     {
00273         pl_VectorConvertC2F_NN (dst, src, numItems);
00274     }
00275     
00276     static inline void convertScaled (float* const dst, const char* const src, const UnsignedLong numItems) throw()
00277     {
00278         convertDirect (dst, src, numItems);
00279         pl_VectorMulF_NN1 (dst, dst, 1.f / PLANK_CHARPEAK_F, numItems);
00280     }    
00281 };
00282 
00283 template<>
00284 class NumericalArrayConverterBase<float, short>
00285 {
00286 public:
00287     static inline void convertDirect (float* const dst, const short* const src, const UnsignedLong numItems) throw()
00288     {
00289         pl_VectorConvertS2F_NN (dst, src, numItems);
00290     }
00291     
00292     static inline void convertScaled (float* const dst, const short* const src, const UnsignedLong numItems) throw()
00293     {
00294         convertDirect (dst, src, numItems);
00295         pl_VectorMulF_NN1 (dst, dst, 1.f / PLANK_SHORTPEAK_F, numItems);
00296     }    
00297 };
00298 
00299 template<>
00300 class NumericalArrayConverterBase<float, Int24>
00301 {
00302 public:
00303     static inline void convertDirect (float* const dst, const Int24* const src, const UnsignedLong numItems) throw()
00304     {
00305         for (UnsignedLong i = 0; i < numItems; ++i)
00306             dst[i] = float (src[i]);
00307     }
00308     
00309     static inline void convertScaled (float* const dst, const Int24* const src, const UnsignedLong numItems) throw()
00310     {
00311         convertDirect (dst, src, numItems);
00312         pl_VectorMulF_NN1 (dst, dst, 1.f / PLANK_INT24PEAK_F, numItems);
00313     }    
00314 };
00315 
00316 template<>
00317 class NumericalArrayConverterBase<float, int>
00318 {
00319 public:
00320     static inline void convertDirect (float* const dst, const int* const src, const UnsignedLong numItems) throw()
00321     {
00322         pl_VectorConvertI2F_NN (dst, src, numItems);
00323     }
00324     
00325     static inline void convertScaled (float* const dst, const int* const src, const UnsignedLong numItems) throw()
00326     {
00327         convertDirect (dst, src, numItems);
00328         pl_VectorMulF_NN1 (dst, dst, 1.f / PLANK_INTPEAK_F, numItems);
00329     }    
00330 };
00331 
00332 template<>
00333 class NumericalArrayConverterBase<short, Int24>
00334 {
00335 public:
00336     static inline void convertDirect (short* const dst, const Int24* const src, const UnsignedLong numItems) throw()
00337     {
00338         for (UnsignedLong i = 0; i < numItems; ++i)
00339             dst[i] = short (src[i]);
00340     }
00341     
00342     static inline void convertScaled (short* const dst, const Int24* const src, const UnsignedLong numItems) throw()
00343     {
00344         for (UnsignedLong i = 0; i < numItems; ++i)
00345             dst[i] = short (int (src[i]) / 256);
00346     }
00347 };
00348 
00349 template<>
00350 class NumericalArrayConverterBase<Int24, short>
00351 {
00352 public:
00353     static inline void convertDirect (Int24* const dst, const short* const src, const UnsignedLong numItems) throw()
00354     {
00355         for (UnsignedLong i = 0; i < numItems; ++i)
00356             dst[i] = Int24 (src[i]);
00357     }
00358     
00359     static inline void convertScaled (Int24* const dst, const short* const src, const UnsignedLong numItems) throw()
00360     {
00361         for (UnsignedLong i = 0; i < numItems; ++i)
00362             dst[i] = Int24 (int (src[i]) * 256);
00363     }
00364 };
00365 
00366 template<>
00367 class NumericalArrayConverterBase<int, Int24>
00368 {
00369 public:
00370     static inline void convertDirect (int* const dst, const Int24* const src, const UnsignedLong numItems) throw()
00371     {
00372         for (UnsignedLong i = 0; i < numItems; ++i)
00373             dst[i] = int (src[i]);
00374     }
00375     
00376     static inline void convertScaled (int* const dst, const Int24* const src, const UnsignedLong numItems) throw()
00377     {
00378         for (UnsignedLong i = 0; i < numItems; ++i)
00379             dst[i] = int (src[i]) * 256;
00380     }
00381 };
00382 
00383 template<>
00384 class NumericalArrayConverterBase<Int24, int>
00385 {
00386 public:
00387     static inline void convertDirect (Int24* const dst, const int* const src, const UnsignedLong numItems) throw()
00388     {
00389         for (UnsignedLong i = 0; i < numItems; ++i)
00390             dst[i] = Int24 (src[i]);
00391     }
00392     
00393     static inline void convertScaled (Int24* const dst, const int* const src, const UnsignedLong numItems) throw()
00394     {
00395         for (UnsignedLong i = 0; i < numItems; ++i)
00396             dst[i] = Int24 (int (src[i]) / 256);
00397     }
00398 };
00399 
00400 template<class SrcType>
00401 class NumericalArrayConverterSIMD
00402 {
00403 };
00404 
00405 template<>
00406 class NumericalArrayConverterSIMD<float>
00407 {
00408 public:
00409     template<class DstType>
00410     static inline void convertScaled (DstType* const dst, const float* const src, const UnsignedLong numItems) throw()
00411     {
00412         PLANK_ALIGN (PLANK_SIMDF_SIZE) 
00413         float temp[PLANK_SIMDF_LENGTH];
00414         
00415         const float factor = TypeUtility<DstType>::getTypePeak();
00416         const UnsignedLong numSIMD = numItems >> PLANK_SIMDF_SHIFT;
00417         const UnsignedLong numRemain = numItems & PLANK_SIMDF_MASK;
00418         
00419         DstType* dstPtr = dst;
00420         const float* srcPtr = src;
00421         
00422         {
00423             PLONK_SHADOW (src);
00424             PLONK_SHADOW (dst);
00425             
00426             for (UnsignedLong i = 0; i < numSIMD; ++i, dstPtr += PLANK_SIMDF_LENGTH, srcPtr += PLANK_SIMDF_LENGTH)
00427             {
00428                 pl_VectorMulF_NN1 (temp, srcPtr, factor, PLANK_SIMDF_LENGTH);
00429                 NumericalArrayConverterBase<DstType,float>::convertDirect (dstPtr, temp, PLANK_SIMDF_LENGTH);
00430             }
00431             
00432             if (numRemain)
00433             {
00434                 pl_VectorMulF_NN1 (temp, srcPtr, factor, numRemain);
00435                 NumericalArrayConverterBase<DstType,float>::convertDirect (dstPtr, temp, numRemain);
00436             }
00437         }
00438     }    
00439 };
00440 
00441 template<>
00442 class NumericalArrayConverterSIMD<double>
00443 {
00444 public:
00445     template<class DstType>
00446     static inline void convertScaled (DstType* const dst, const double* const src, const UnsignedLong numItems) throw()
00447     {
00448         PLANK_ALIGN (PLANK_SIMDD_SIZE) 
00449         double temp[PLANK_SIMDD_LENGTH];
00450         
00451         const double factor = TypeUtility<DstType>::getTypePeak();
00452         const UnsignedLong numSIMD = numItems >> PLANK_SIMDD_SHIFT;
00453         const UnsignedLong numRemain = numItems & PLANK_SIMDD_MASK;
00454         
00455         DstType* dstPtr = dst;
00456         const double* srcPtr = src;
00457 
00458         {
00459             PLONK_SHADOW (src);
00460             PLONK_SHADOW (dst);
00461             
00462             for (UnsignedLong i = 0; i < numSIMD; ++i, dstPtr += PLANK_SIMDD_LENGTH, srcPtr += PLANK_SIMDD_LENGTH)
00463             {
00464                 pl_VectorMulD_NN1 (temp, srcPtr, factor, PLANK_SIMDD_LENGTH);
00465                 NumericalArrayConverterBase<DstType,double>::convertDirect (dstPtr, temp, PLANK_SIMDD_LENGTH);
00466             }
00467             
00468             if (numRemain)
00469             {
00470                 pl_VectorMulD_NN1 (temp, srcPtr, factor, numRemain);
00471                 NumericalArrayConverterBase<DstType,double>::convertDirect (dstPtr, temp, numRemain);
00472             }
00473         }
00474     }    
00475 };
00476 
00477 
00478 template<>
00479 class NumericalArrayConverterBase<char, float>
00480 {
00481 public:
00482     static inline void convertDirect (char* const dst, const float* const src, const UnsignedLong numItems) throw()
00483     {
00484         pl_VectorConvertF2C_NN (dst, src, numItems);
00485     }
00486     
00487     static inline void convertScaled (char* const dst, const float* const src, const UnsignedLong numItems) throw()
00488     {
00489         NumericalArrayConverterSIMD<float>::convertScaled (dst, src, numItems);
00490     }    
00491 };
00492 
00493 template<>
00494 class NumericalArrayConverterBase<short, float>
00495 {
00496 public:
00497     static inline void convertDirect (short* const dst, const float* const src, const UnsignedLong numItems) throw()
00498     {
00499         pl_VectorConvertF2S_NN (dst, src, numItems);
00500     }
00501     
00502     static inline void convertScaled (short* const dst, const float* const src, const UnsignedLong numItems) throw()
00503     {
00504         NumericalArrayConverterSIMD<float>::convertScaled (dst, src, numItems);
00505     }    
00506 };
00507 
00508 template<>
00509 class NumericalArrayConverterBase<Int24, float>
00510 {
00511 public:
00512     static inline void convertDirect (Int24* const dst, const float* const src, const UnsignedLong numItems) throw()
00513     {
00514         for (UnsignedLong i = 0; i < numItems; ++i)
00515             dst[i] = Int24 (src[i]);
00516     }
00517     
00518     static inline void convertScaled (Int24* const dst, const float* const src, const UnsignedLong numItems) throw()
00519     {
00520         NumericalArrayConverterSIMD<float>::convertScaled (dst, src, numItems);
00521     }    
00522 };
00523 
00524 template<>
00525 class NumericalArrayConverterBase<int, float>
00526 {
00527 public:
00528     static inline void convertDirect (int* const dst, const float* const src, const UnsignedLong numItems) throw()
00529     {
00530         pl_VectorConvertF2I_NN (dst, src, numItems);
00531     }
00532     
00533     static inline void convertScaled (int* const dst, const float* const src, const UnsignedLong numItems) throw()
00534     {
00535         NumericalArrayConverterSIMD<float>::convertScaled (dst, src, numItems);
00536     }    
00537 };
00538 
00539 template<class NumericalType, class OtherType>
00540 class NumericalArrayConverter : public NumericalArrayConverterBase<NumericalType,OtherType>
00541 {
00542 public:
00543     typedef NumericalArrayConverterBase<NumericalType,OtherType> Base;
00544     
00545     static inline void convert (NumericalType* const dst, 
00546                                 const OtherType* const src, 
00547                                 const UnsignedLong numItems,
00548                                 const bool applyScaling) throw()
00549     {
00550         if (applyScaling)   Base::convertScaled (dst, src, numItems);
00551         else                Base::convertDirect (dst, src, numItems);
00552     }
00553 };
00554 
00555 // copy types when src and dst types are the same
00556 template<> class NumericalArrayConverter<float,float>       : public NumericalArrayConverterCopy<float> { };
00557 template<> class NumericalArrayConverter<double,double>     : public NumericalArrayConverterCopy<double> { };
00558 template<> class NumericalArrayConverter<char,char>         : public NumericalArrayConverterCopy<char> { };
00559 template<> class NumericalArrayConverter<short,short>       : public NumericalArrayConverterCopy<short> { };
00560 template<> class NumericalArrayConverter<int,int>           : public NumericalArrayConverterCopy<int> { };
00561 template<> class NumericalArrayConverter<Int24,Int24>       : public NumericalArrayConverterCopy<Int24> { };
00562 template<> class NumericalArrayConverter<LongLong,LongLong> : public NumericalArrayConverterCopy<LongLong> { };
00563 
00564 //------------------------------------------------------------------------------
00565 
00566 template<class NumericalType, PLONK_BINARYOPFUNCTION(NumericalType, op)>
00567 class NumericalArrayBinaryOpBase
00568 {
00569 public:
00570     static inline void calcNN (NumericalType* dst, const NumericalType* left, const NumericalType* right, const UnsignedLong numItems) throw()
00571     {
00572         for (UnsignedLong i = 0; i < numItems; ++i)
00573             dst[i] = op (left[i], right[i]);
00574     }
00575     
00576     static inline void calcN1 (NumericalType* dst, const NumericalType* left, const NumericalType right, const UnsignedLong numItems) throw()
00577     {
00578         for (UnsignedLong i = 0; i < numItems; ++i)
00579             dst[i] = op (left[i], right);
00580     }
00581     
00582     static inline void calc1N (NumericalType* dst, const NumericalType left, const NumericalType* right, const UnsignedLong numItems) throw()
00583     {
00584         for (UnsignedLong i = 0; i < numItems; ++i)
00585             dst[i] = op (left, right[i]);
00586     }
00587 };
00588 
00589 template<class NumericalType, PLONK_BINARYOPFUNCTION(NumericalType, op)>
00590 class NumericalArrayBinaryOp : public NumericalArrayBinaryOpBase<NumericalType,op>
00591 {
00592 };
00593 
00594 #define PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE,PLONKOP,PLANKOP)\
00595     template<>\
00596     class  NumericalArrayBinaryOp    <Plank##TYPECODE, BinaryOpFunctionsHelper<Plank##TYPECODE>::BinaryOpFunctionsType::PLONKOP> \
00597     :\
00598     public NumericalArrayBinaryOpBase<Plank##TYPECODE, BinaryOpFunctionsHelper<Plank##TYPECODE>::BinaryOpFunctionsType::PLONKOP> \
00599     {\
00600     public:\
00601         static inline void calcNN (Plank##TYPECODE* dst, const Plank##TYPECODE* left, const Plank##TYPECODE* right, const UnsignedLong numItems) throw() {\
00602             pl_Vector##PLANKOP##TYPECODE##_NNN (dst, left, right, numItems);\
00603         }\
00604         \
00605         static inline void calcN1 (Plank##TYPECODE* dst, const Plank##TYPECODE* left, const Plank##TYPECODE right, const UnsignedLong numItems) throw() {\
00606             pl_Vector##PLANKOP##TYPECODE##_NN1 (dst, left, right, numItems);\
00607         }\
00608         \
00609         static inline void calc1N (Plank##TYPECODE* dst, const Plank##TYPECODE left, const Plank##TYPECODE* right, const UnsignedLong numItems) throw() {\
00610             pl_Vector##PLANKOP##TYPECODE##_N1N (dst, left, right, numItems);\
00611         }\
00612     }
00613 
00614 #define PLONK_NUMERICALARRAYBINARYOPS_DEFINE(TYPECODE)\
00615     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, addop, Add);\
00616     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, subop, Sub);\
00617     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, mulop, Mul);\
00618     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, divop, Div);\
00619     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, modop, Mod);\
00620     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, min, Min);\
00621     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, max, Max);\
00622     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, pow, Pow);\
00623     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, isEqualTo, IsEqualTo);\
00624     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, isNotEqualTo, IsNotEqualTo);\
00625     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, isGreaterThan, IsGreaterThan);\
00626     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, isGreaterThanOrEqualTo, IsGreaterThanOrEqualTo);\
00627     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, isLessThan, IsLessThan);\
00628     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, isLessThanOrEqualTo, IsLessThanOrEqualTo);\
00629     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, hypot, Hypot);\
00630     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, atan2, Atan2);\
00631     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, sumsqr, SumSqr);\
00632     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, difsqr, DifSqr);\
00633     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, sqrsum, SqrSum);\
00634     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, sqrdif, SqrDif);\
00635     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, absdif, AbsDif);\
00636     PLONK_NUMERICALARRAYBINARYOP_DEFINE(TYPECODE, thresh, Thresh)
00637 
00638 PLONK_NUMERICALARRAYBINARYOPS_DEFINE(F);
00639 PLONK_NUMERICALARRAYBINARYOPS_DEFINE(D);
00640 
00641 
00642 
00643 
00644 //------------------------------------------------------------------------------
00645 
00646 template<class NumericalType, PLONK_UNARYOPFUNCTION(NumericalType, op)>
00647 class NumericalArrayUnaryOpBase
00648 {
00649 public:
00650     static inline void calc (NumericalType* dst, const NumericalType* src, const UnsignedLong numItems) throw()
00651     {
00652         for (UnsignedLong i = 0; i < numItems; ++i)
00653             dst[i] = op (src[i]);
00654     }    
00655 };
00656 
00657 template<class NumericalType, PLONK_UNARYOPFUNCTION(NumericalType, op)>
00658 class NumericalArrayUnaryOp : public NumericalArrayUnaryOpBase<NumericalType,op>
00659 {
00660 };
00661 
00662 
00663 
00664 #define PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE,PLONKOP,PLANKOP)\
00665     template<>\
00666     class  NumericalArrayUnaryOp    <Plank##TYPECODE, UnaryOpFunctionsHelper<Plank##TYPECODE>::UnaryOpFunctionsType::PLONKOP> \
00667     :\
00668     public NumericalArrayUnaryOpBase<Plank##TYPECODE, UnaryOpFunctionsHelper<Plank##TYPECODE>::UnaryOpFunctionsType::PLONKOP> \
00669     {\
00670     public:\
00671         static inline void calc (Plank##TYPECODE* dst, const Plank##TYPECODE* src, const UnsignedLong numItems) throw() {\
00672             pl_Vector##PLANKOP##TYPECODE##_NN (dst, src, numItems);\
00673         }\
00674     }
00675 
00676 #define PLONK_NUMERICALARRAYUNARYOPS_DEFINE(TYPECODE)\
00677     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, move, Move);\
00678     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, neg, Neg);\
00679     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, abs, Abs);\
00680     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, log2, Log2);\
00681     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, reciprocal, Reciprocal);\
00682     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, sin, Sin);\
00683     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, cos, Cos);\
00684     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, tan, Tan);\
00685     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, asin, Asin);\
00686     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, acos, Acos);\
00687     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, atan, Atan);\
00688     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, sinh, Sinh);\
00689     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, cosh, Cosh);\
00690     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, tanh, Tanh);\
00691     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, sqrt, Sqrt);\
00692     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, log, Log);\
00693     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, log10, Log10);\
00694     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, exp, Exp);\
00695     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, squared, Squared);\
00696     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, cubed, Cubed);\
00697     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, ceil, Ceil);\
00698     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, floor, Floor);\
00699     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, frac, Frac);\
00700     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, sign , Sign);\
00701     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, m2f, M2F);\
00702     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, f2m, F2M);\
00703     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, a2dB, A2dB);\
00704     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, dB2a, dB2A);\
00705     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, d2r, D2R);\
00706     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, r2d, R2D);\
00707     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, distort, Distort);\
00708     PLONK_NUMERICALARRAYUNARYOP_DEFINE(TYPECODE, zap, Zap)
00709 
00710 PLONK_NUMERICALARRAYUNARYOPS_DEFINE(F);
00711 PLONK_NUMERICALARRAYUNARYOPS_DEFINE(D);
00712 
00713 
00714 //------------------------------------------------------------------------------
00715 
00716 template<class NumericalType>
00717 class NumericalArrayComplex
00718 {
00719 public:
00720     inline static void zmul (NumericalType* dstReal,
00721                              NumericalType* dstimag,
00722                              const NumericalType* leftReal,
00723                              const NumericalType* leftImag,
00724                              const NumericalType* rightReal,
00725                              const NumericalType* rightImag,
00726                              const UnsignedLong numItems) throw()
00727     {
00728         for (UnsignedLong i = 0; i < numItems; ++i)
00729         {
00730             dstReal[i] = leftReal[i] * rightReal[i] - leftImag[i] * rightImag[i];
00731             dstimag[i] = leftReal[i] * rightImag[i] + leftImag[i] * rightReal[i];
00732         }
00733     }
00734 };
00735 
00736 template<>
00737 class NumericalArrayComplex<float>
00738 {
00739 public:
00740     inline static void zmul (float* dstReal,
00741                              float* dstimag,
00742                              const float* leftReal,
00743                              const float* leftImag,
00744                              const float* rightReal,
00745                              const float* rightImag,
00746                              const UnsignedLong numItems) throw()
00747     {
00748         pl_VectorZMulF_ZNNNNN (dstReal, dstimag, leftReal, leftImag, rightReal, rightImag, numItems);
00749     }
00750 };
00751 
00752 template<>
00753 class NumericalArrayComplex<double>
00754 {
00755 public:
00756     inline static void zmul (double* dstReal,
00757                              double* dstimag,
00758                              const double* leftReal,
00759                              const double* leftImag,
00760                              const double* rightReal,
00761                              const double* rightImag,
00762                              const UnsignedLong numItems) throw()
00763     {
00764         pl_VectorZMulD_ZNNNNN (dstReal, dstimag, leftReal, leftImag, rightReal, rightImag, numItems);
00765     }
00766 };
00767 
00768 
00769 //------------------------------------------------------------------------------
00770 
00772 class NumericalArraySpec
00773 {
00774 public:
00775         NumericalArraySpec (const int size, const bool zeroData) throw() 
00776         :       size_ (size), 
00777         zeroData_ (zeroData) 
00778         { 
00779         }
00780         
00781         const int size_;
00782         const bool zeroData_;
00783     
00784 private:
00785         NumericalArraySpec& operator= (NumericalArraySpec const&); // to prevent assignment and MSVC complaining!
00786 };
00787 
00801 template<class NumericalType>
00802 class NumericalArray : public ObjectArray<NumericalType>
00803 {
00804 public:
00805     typedef ObjectArrayInternal<NumericalType>          Internal;
00806     typedef ObjectArray<NumericalType>                  Base;   
00807     typedef WeakPointerContainer<NumericalArray>        Weak;
00808     
00809     typedef ObjectArray<NumericalType>                  ObjectArrayType;
00810     typedef ObjectArray<ObjectArrayType>                ObjectArray2DType;
00811     
00812     typedef typename BinaryOpFunctionsHelper<NumericalType>::BinaryOpFunctionsType BinaryOpFunctionsType;
00813     typedef typename UnaryOpFunctionsHelper<NumericalType>::UnaryOpFunctionsType UnaryOpFunctionsType;
00814 
00815         class InitialNumber
00816         {
00817         public:
00818                 inline InitialNumber() throw() : value (0), valid (false) { }
00819                 inline InitialNumber (NumericalType initialValue) throw()
00820                 :       value (initialValue), 
00821             valid (true) 
00822                 { 
00823                 }
00824 
00825                 template<class OtherType>
00826                 inline InitialNumber (OtherType initialValue) throw()
00827                 :       value (static_cast<const NumericalType> (initialValue)), 
00828             valid (true) 
00829                 { 
00830                 }
00831                 
00832                 const NumericalType value;
00833                 const bool valid;
00834 
00835         private:
00836                 InitialNumber& operator= (InitialNumber const&); // to prevent assignment and MSVC complaining!
00837         };
00838         
00839         NumericalArray() throw()
00840         :       Base (0, false)
00841         {
00842         }       
00843         
00844     explicit NumericalArray (Internal* internal) throw() 
00845         :       Base (internal)
00846         {
00847         }
00848     
00849     PLONKSMARTPOINTERCONTAINER_DEEPCOPY(NumericalArray,Internal)
00850         
00851     
00854     static NumericalArray fromWeak (Weak const& weak) throw()
00855     {
00856         return weak.fromWeak();
00857     }
00858         
00859     static const NumericalArray& getNull() throw()
00860         {
00861                 static NumericalArray null;
00862                 return null;
00863         }               
00864     
00865     static inline void copyData (NumericalType* const dst, const NumericalType* const src, const UnsignedLong numItems) throw()
00866     {
00867         Memory::copy (dst, src, numItems * sizeof (NumericalType));
00868     }
00869         
00870     static inline void convertDirect (NumericalType* const dst, const NumericalType* const src, const UnsignedLong numItems) throw()
00871     {
00872         copyData (dst, src, numItems);
00873     }
00874     
00875     static inline void convertScaled (NumericalType* const dst, const NumericalType* const src, const UnsignedLong numItems) throw()
00876     {
00877         copyData (dst, src, numItems);
00878     }
00879 
00880     template<class OtherType>
00881     static inline void convertDirect (NumericalType* const dst, const OtherType* const src, const UnsignedLong numItems) throw()
00882     {
00883         NumericalArrayConverter<NumericalType,OtherType>::convertDirect (dst, src, numItems);        
00884     }
00885     
00886     template<class OtherType>
00887     static inline void convertScaled (NumericalType* const dst, const OtherType* const src, const UnsignedLong numItems) throw()
00888     {
00889         NumericalArrayConverter<NumericalType,OtherType>::convertScaled (dst, src, numItems);        
00890     }
00891     
00892     static inline void convert (NumericalType* const dst, 
00893                                 const NumericalType* const src, 
00894                                 const UnsignedLong numItems,
00895                                 const bool applyScaling) throw()
00896     {
00897         (void)applyScaling;
00898         copyData (dst, src, numItems);
00899     }    
00900     
00901     template<class OtherType>
00902     static inline void convert (NumericalType* const dst, 
00903                                 const OtherType* const src, 
00904                                 const UnsignedLong numItems,
00905                                 const bool applyScaling) throw()
00906     {
00907         NumericalArrayConverter<NumericalType,OtherType>::convert (dst, src, numItems, applyScaling);        
00908     }
00909     
00910     static inline void zeroData (NumericalType* const dst, const UnsignedLong numItems) throw()
00911     {
00912         Memory::zero (dst, numItems * sizeof (NumericalType));
00913     }
00914     
00915     static inline void fill (NumericalType* const dst, const NumericalType value, const UnsignedLong numItems) throw()
00916     {
00917         NumericalArrayFiller<NumericalType>::fill (dst, value, numItems);
00918     }
00919     
00920     inline void fill (const NumericalType value) throw()
00921     {
00922         const int length = this->length();
00923         
00924         if (length > 0)
00925         {
00926             NumericalType *thisArray = this->getArray();
00927             NumericalArrayFiller<NumericalType>::fill (this->getArray(), value, length);
00928         }
00929     }
00930     
00931     inline NumericalArray (NumericalArray const& copy) throw()
00932         :       Base (static_cast<Base const&> (copy))
00933         {
00934         }    
00935     
00937     inline NumericalArray& operator= (NumericalArray const& other) throw()
00938         {
00939                 if (this != &other)
00940             this->setInternal (other.getInternal());
00941         
00942         return *this;
00943         }
00944 
00945     inline NumericalArray (ObjectArray<NumericalType> const& copy) throw()
00946         :       Base (static_cast<Base const&> (copy))
00947         {
00948         }    
00949        
00950     NumericalArray (Dynamic const& other) throw()
00951     :   Base (other.as<NumericalArray>().getInternal())
00952     {
00953     }    
00954         
00955 public:
00957         template<class CopyType>
00958         NumericalArray (NumericalArray<CopyType> const& copy) throw()
00959         :       Base (copy.size(), copy.isNullTerminated())
00960         {               
00961                 NumericalType *thisArray = this->getArray();
00962                 const CopyType *copyArray = copy.getArray();
00963                 
00964                 if (thisArray != 0 && copyArray != 0)
00965             NumericalArray::convertDirect (thisArray, copyArray, this->size());
00966         }
00967         
00970         template<class CopyType>
00971         NumericalArray (ObjectArray<CopyType> const& copy) throw()
00972         :   Base (copy.size(), copy.isNullTerminated())
00973         {               
00974                 NumericalType *thisArray = this->getArray();
00975                 const CopyType *copyArray = copy.getArray();
00976                 
00977                 if (thisArray != 0 && copyArray != 0)
00978             NumericalArray::convertData (thisArray, copyArray, this->size());
00979         }
00980         
00982         NumericalArray (NumericalArray const& array0, 
00983                                     NumericalArray const& array1) throw()
00984         :       Base (array0, array1)
00985         {
00986         }
00987         
00988         ObjectArrayConcatOperatorsDefine(NumericalArray, NumericalType)
00989                 
00990         
00992         NumericalArray (NumericalArraySpec const& spec) throw()
00993         :       Base (spec.size_, false)
00994         {
00995                 if (spec.zeroData_) 
00996             zero();
00997         }
00998         
01002         NumericalArray (NumericalArraySpec const& spec, const bool needsNullTermination) throw()
01003         :       Base (spec.size_, needsNullTermination)
01004         {
01005                 if (spec.zeroData_) 
01006             zero();
01007         }
01008         
01009 //      /** Construct a NumericalArray that refers to some other data.
01010 //       It is very important to note that the data is not copies so must continue
01011 //       to exist for the lifetime of this object. 
01012 //       @param size The size of the source data to use.
01013 //       @param dataToUse A pointer to the data. 
01014 //       @param needsNullTermination Whether the data is null terminated ot not. 
01015 //       @see withArrayNoCopy */
01016 //      NumericalArray (const int size, NumericalType* dataToUse, const bool needsNullTermination, const bool shouldTakeOwnership = false) throw()
01017 //      :       Base (size, dataToUse, needsNullTermination, shouldTakeOwnership)
01018 //      {
01019 //              plonk_assert (size > 0);
01020 //      }
01021         
01023         static NumericalArray<NumericalType> withSize (const int size, const bool zeroData = false) throw()
01024         {
01025                 return NumericalArray<NumericalType> (NumericalArraySpec(size, zeroData));
01026         }
01027         
01029         static NumericalArray<NumericalType> newClear (const int size) throw()
01030         {
01031                 return NumericalArray<NumericalType> (NumericalArraySpec(size, true));
01032         }
01033                 
01035         static NumericalArray<NumericalType> line (const int size, const NumericalType start, const NumericalType end) throw()
01036         {
01037                 plonk_assert (size >= 2);
01038                 
01039                 const int numValues = size < 2 ? 2 : size;
01040                 
01041                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01042         NumericalArrayFiller<NumericalType>::line (newArray.getArray(), numValues, start, end);
01043 
01044                 return newArray;
01045         }
01046         
01048         static NumericalArray<NumericalType> series (const int size, 
01049                                                                                                  const NumericalType start, 
01050                                                                                                  const NumericalType grow) throw()
01051         {
01052                 plonk_assert (size >= 2);
01053                 
01054                 const int numValues = size < 2 ? 2 : size;
01055                 
01056                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01057         NumericalArrayFiller<NumericalType>::series (newArray.getArray(), numValues, start, grow);
01058                 
01059                 return newArray;                
01060         }
01061         
01063         static NumericalArray<NumericalType> geom (const int size, 
01064                                                                                            const NumericalType start, 
01065                                                                                            const NumericalType grow) throw()
01066         {
01067                 plonk_assert (size >= 2);
01068                 
01069                 const int numValues = size < 2 ? 2 : size;
01070                 
01071                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01072         NumericalArrayFiller<NumericalType>::geom (newArray.getArray(), numValues, start, grow);
01073                 
01074                 return newArray;                
01075         }
01076         
01079         static NumericalArray<NumericalType> rand (const int size, 
01080                                                                                            const NumericalType lower, 
01081                                                                                            const NumericalType upper) throw()
01082         {
01083                 plonk_assert (size > 0);
01084                 
01085                 const int numValues = size < 1 ? 1 : size;
01086                 
01087                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01088         NumericalArrayFiller<NumericalType>::rand (newArray.getArray(), numValues, lower, upper);
01089                 
01090                 return newArray;
01091         }
01092     
01095     static NumericalArray<NumericalType> rand (const int size, 
01096                                                                                            const NumericalType upper) throw()
01097     {
01098                 plonk_assert (size > 0);
01099                 
01100                 const int numValues = size < 1 ? 1 : size;
01101                 
01102                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01103         NumericalArrayFiller<NumericalType>::rand (newArray.getArray(), numValues, upper);
01104                 
01105                 return newArray;
01106     }
01107         
01110         static NumericalArray<NumericalType> rand2 (const int size, 
01111                                                                                             const NumericalType positive) throw()
01112         {
01113                 plonk_assert (size > 0);
01114                 
01115                 const int numValues = size < 1 ? 1 : size;
01116                 
01117                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01118         NumericalArrayFiller<NumericalType>::rand2 (newArray.getArray(), numValues, positive);
01119                 
01120                 return newArray;
01121         }
01122         
01127         static NumericalArray<NumericalType> exprand (const int size, 
01128                                                                                                   const NumericalType lower, 
01129                                                                                                   const NumericalType upper) throw()
01130         {
01131                 plonk_assert (size > 0);
01132                 
01133                 const int numValues = size < 1 ? 1 : size;
01134                 
01135                 NumericalArray<NumericalType> newArray = NumericalArray<NumericalType>::withSize (numValues);
01136         NumericalArrayFiller<NumericalType>::exprand (newArray.getArray(), numValues, lower, upper);
01137                 
01138                 return newArray;
01139         }
01140         
01141         
01143         static NumericalArray<NumericalType> sineTable (const int size, 
01144                                                                                                     const double repeats = 1.0, 
01145                                                                                                     const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01146         {
01147                 plonk_assert (repeats > 0.f);
01148                 return NumericalArray<double>::line (size, 0.0, Math<double>::get2Pi() * repeats).sin() * peak;
01149         }
01150         
01151     static NumericalArray<NumericalType> harmonicTable (const int size, 
01152                                                         NumericalArray<NumericalType> const& weights) throw()
01153         {
01154                 plonk_assert (weights.length() > 0);
01155         
01156         NumericalArray<double> result = NumericalArray<double>::newClear (size);
01157         
01158         for (int i = 0; i < weights.length(); ++i)
01159         {
01160             const int harmonic = i + 1;
01161             result += NumericalArray<double>::line (size, 0.0, Math<double>::get2Pi() * harmonic).sin() * weights.atUnchecked (i);
01162         }
01163         
01164                 return result;
01165         }
01166     
01168         static NumericalArray<NumericalType> cosineTable (const int size, 
01169                                                                                                           const double repeats = 1.0, 
01170                                                                                                           const NumericalType peak = NumericalType(0)) throw()
01171         {
01172                 plonk_assert (repeats > 0.f);
01173         NumericalType actualPeak = peak == NumericalType(0) ? TypeUtility<NumericalType>::getTypePeak() : peak;
01174                 return NumericalArray<double>::line (size, 0.0, Math<double>::get2Pi() * repeats).cos() * actualPeak;
01175         }
01176         
01178         static NumericalArray<NumericalType> cosineWindow (const int size, 
01179                                                                                                            const double repeats = 1.0, 
01180                                                                                                            const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01181         {
01182                 plonk_assert (repeats > 0.f);
01183                 return NumericalArray<double>::line (size, 0.0, Math<double>::getPi() * repeats).sin() * peak;
01184         }
01185         
01187         static NumericalArray<NumericalType> triangleWindow (const int size, 
01188                                                                                                                  const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01189         {
01190                 NumericalArray<NumericalType> bartlett = NumericalArray<NumericalType>::bartlettWindow (size+2, peak);
01191                 return bartlett.range (1, size + 1);
01192         }
01193         
01195         static NumericalArray<NumericalType> bartlettWindow (const int size, 
01196                                                                                                                  const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01197         {
01198                 return -NumericalArray<NumericalType>::line (size, -peak, peak).abs() + NumericalArray<NumericalType> (peak);
01199         }
01200         
01202         static NumericalArray<NumericalType> hannWindow (const int size, 
01203                                                                                                          const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01204         {
01205                 return (-NumericalArray<double>::cosineTable (size) + 1.0) * 0.5f * peak;
01206         }
01207         
01209         static NumericalArray<NumericalType> hammingWindow (const int size, 
01210                                                                                                             const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01211         {
01212                 return (-NumericalArray<double>::cosineTable (size) * 0.46 + 0.54) * peak;
01213         }
01214         
01216         static NumericalArray<NumericalType> blackmanWindow (const int size, 
01217                                                          const double alpha = 0.16, 
01218                                                                                                                  const NumericalType peak = TypeUtility<NumericalType>::getTypePeak()) throw()
01219         {
01220                 double a0 = (1.0 - alpha) * 0.5;
01221                 double a1 = 0.5;
01222                 double a2 = alpha * 0.5;
01223                 
01224                 return (-NumericalArray<double>::cosineTable (size) * a1 + NumericalArray<double>::cosineTable (size, 2.0) * a2 + a0) * peak;
01225         }
01226         
01227         static int sourceLength (const NumericalType* nullTerminatedSourceArray) throw()
01228         {
01229                 plonk_assert (nullTerminatedSourceArray != 0);
01230                 
01231                 int size = 0;
01232                 
01233                 while (nullTerminatedSourceArray[size])
01234                         size++;
01235                 
01236                 return size;
01237         }
01238         
01239         static int sourceSize (const NumericalType* nullTerminatedSourceArray) throw()
01240         {
01241                 return sourceLength (nullTerminatedSourceArray) + 1;
01242         }
01243         
01244         
01246         NumericalArray (const NumericalType* nullTerminatedSourceArray) throw()
01247         :       ObjectArray<NumericalType> (sourceSize (nullTerminatedSourceArray), true)
01248         {
01249                 plonk_assert (nullTerminatedSourceArray != 0);
01250                 
01251                 NumericalType *thisArray = this->getArray();
01252                 
01253                 if (thisArray != 0)
01254             copyData (thisArray, nullTerminatedSourceArray, this->size());
01255         }
01256         
01258         static NumericalArray<NumericalType> withArray (const int size, 
01259                                                                                                     const NumericalType* sourceArray, 
01260                                                                                                     const bool needsNullTermination = false) throw()
01261         {
01262                 plonk_assert (sourceArray != 0);
01263                 
01264                 NumericalArray<NumericalType> result = NumericalArray<NumericalType> (NumericalArraySpec (size, false), 
01265                                                                                                                                                           needsNullTermination);
01266                 
01267                 NumericalType *thisArray = result.getArray();
01268                 
01269                 if (thisArray != 0)
01270                 {            
01271                         if (needsNullTermination)
01272                         {
01273                                 const int length = size - 1;                            
01274                 copyData (thisArray, sourceArray, length);
01275                                 thisArray[length] = NumericalType (0);
01276                         }
01277                         else
01278                         {
01279                 copyData (thisArray, sourceArray, size);
01280                         }
01281                 }
01282                 
01283                 return result;
01284         }
01285         
01289         static NumericalArray<NumericalType> withArrayNoCopy (const int size, 
01290                                                                                                                   NumericalType* sourceArray, 
01291                                                                                                                   const bool needsNullTermination = false) throw()
01292         {
01293                 plonk_assert (sourceArray != 0);
01294                 return Base (size, sourceArray, needsNullTermination);
01295         }
01296         
01298     template<class OtherType>
01299     NumericalArray (OtherType const& value) throw()
01300         :       Base (NumericalType (value))
01301         {
01302         }
01303     
01304 //      NumericalArray (NumericalType value) throw()
01305 //      :       Base (value)
01306 //      {
01307 //      }
01308 
01309 protected:
01310         static int countValidInitialisers (InitialNumber const& i03) throw()
01311         {
01312                 int size = 3;
01313                 if (i03.valid) size++; else return size;
01314                 return size;
01315         }       
01316 
01317 public:
01318         NumericalArray (InitialNumber const &i00,
01319                                     InitialNumber const &i01,
01320                                     InitialNumber const &i02,
01321                                     InitialNumber const &i03 = InitialNumber()) throw()
01322         :       Base (countValidInitialisers (i03), false)
01323         {
01324                 NumericalType *thisArray = this->getArray();
01325                 
01326                 if (i00.valid) thisArray[ 0] = i00.value; else return;
01327                 if (i01.valid) thisArray[ 1] = i01.value; else return;
01328                 if (i02.valid) thisArray[ 2] = i02.value; else return;
01329                 if (i03.valid) thisArray[ 3] = i03.value; else return;
01330         }
01331         
01332 protected:
01333         static int countValidInitialisers (InitialNumber const &i05,
01334                                                                            InitialNumber const &i06,
01335                                                                            InitialNumber const &i07) throw()
01336         {
01337                 int size = 5;
01338                 
01339                 if (i05.valid) size++; else return size;
01340                 if (i06.valid) size++; else return size;
01341                 if (i07.valid) size++; else return size;
01342                 
01343                 return size;
01344         }
01345         
01346 public:
01347         NumericalArray (InitialNumber const &i00,
01348                                     InitialNumber const &i01,
01349                                     InitialNumber const &i02,
01350                                     InitialNumber const &i03,
01351                                     InitialNumber const &i04,
01352                                     InitialNumber const &i05 = InitialNumber(),
01353                                     InitialNumber const &i06 = InitialNumber(),
01354                                     InitialNumber const &i07 = InitialNumber()) throw()
01355         :       Base (countValidInitialisers (i05, i06, i07), 
01356               false)
01357         {
01358                 NumericalType *thisArray = this->getArray();
01359                 
01360                 if (i00.valid) thisArray[ 0] = i00.value; else return;
01361                 if (i01.valid) thisArray[ 1] = i01.value; else return;
01362                 if (i02.valid) thisArray[ 2] = i02.value; else return;
01363                 if (i03.valid) thisArray[ 3] = i03.value; else return;
01364                 if (i04.valid) thisArray[ 4] = i04.value; else return;
01365                 if (i05.valid) thisArray[ 5] = i05.value; else return;
01366                 if (i06.valid) thisArray[ 6] = i06.value; else return;
01367                 if (i07.valid) thisArray[ 7] = i07.value; else return;
01368         }
01369         
01370 protected:
01371         static int countValidInitialisers (InitialNumber const &i09,
01372                                                                            InitialNumber const &i10,
01373                                                                            InitialNumber const &i11,
01374                                                                            InitialNumber const &i12,
01375                                                                            InitialNumber const &i13,
01376                                                                            InitialNumber const &i14,
01377                                                                            InitialNumber const &i15) throw()
01378         {
01379                 int size = 9;
01380                 
01381                 if (i09.valid) size++; else return size;
01382                 if (i10.valid) size++; else return size;
01383                 if (i11.valid) size++; else return size;
01384                 if (i12.valid) size++; else return size;
01385                 if (i13.valid) size++; else return size;
01386                 if (i14.valid) size++; else return size;
01387                 if (i15.valid) size++; else return size;
01388                 
01389                 return size;
01390         }
01391 
01392 public:
01393         NumericalArray (InitialNumber const &i00,
01394                                     InitialNumber const &i01,
01395                                     InitialNumber const &i02,
01396                                     InitialNumber const &i03,
01397                                     InitialNumber const &i04,
01398                                     InitialNumber const &i05,
01399                                     InitialNumber const &i06,
01400                                     InitialNumber const &i07,
01401                                     InitialNumber const &i08,
01402                                     InitialNumber const &i09 = InitialNumber(),
01403                                     InitialNumber const &i10 = InitialNumber(),
01404                                     InitialNumber const &i11 = InitialNumber(),
01405                                     InitialNumber const &i12 = InitialNumber(),
01406                                     InitialNumber const &i13 = InitialNumber(),
01407                                     InitialNumber const &i14 = InitialNumber(),
01408                                     InitialNumber const &i15 = InitialNumber()) throw()
01409         :       Base (countValidInitialisers (i09, i10, i11, i12, i13, i14, i15), 
01410               false)
01411         {
01412                 NumericalType *thisArray = this->getArray();
01413                 
01414                 if (i00.valid) thisArray[ 0] = i00.value; else return;
01415                 if (i01.valid) thisArray[ 1] = i01.value; else return;
01416                 if (i02.valid) thisArray[ 2] = i02.value; else return;
01417                 if (i03.valid) thisArray[ 3] = i03.value; else return;
01418                 if (i04.valid) thisArray[ 4] = i04.value; else return;
01419                 if (i05.valid) thisArray[ 5] = i05.value; else return;
01420                 if (i06.valid) thisArray[ 6] = i06.value; else return;
01421                 if (i07.valid) thisArray[ 7] = i07.value; else return;
01422                 if (i08.valid) thisArray[ 8] = i08.value; else return;
01423                 if (i09.valid) thisArray[ 9] = i09.value; else return;
01424                 if (i10.valid) thisArray[10] = i10.value; else return;
01425                 if (i11.valid) thisArray[11] = i11.value; else return;
01426                 if (i12.valid) thisArray[12] = i12.value; else return;
01427                 if (i13.valid) thisArray[13] = i13.value; else return;
01428                 if (i14.valid) thisArray[14] = i14.value; else return;
01429                 if (i15.valid) thisArray[15] = i15.value; else return;
01430         }
01431         
01432 protected:
01433         static int countValidInitialisers (InitialNumber const &i17,
01434                                                                            InitialNumber const &i18,
01435                                                                            InitialNumber const &i19,
01436                                                                            InitialNumber const &i20,
01437                                                                            InitialNumber const &i21,
01438                                                                            InitialNumber const &i22,
01439                                                                            InitialNumber const &i23,
01440                                                                            InitialNumber const &i24,
01441                                                                            InitialNumber const &i25,
01442                                                                            InitialNumber const &i26,
01443                                                                            InitialNumber const &i27,
01444                                                                            InitialNumber const &i28,
01445                                                                            InitialNumber const &i29,
01446                                                                            InitialNumber const &i30,
01447                                                                            InitialNumber const &i31) throw()
01448         {
01449                 int size = 17;
01450                 
01451                 if (i17.valid) size++; else return size;
01452                 if (i18.valid) size++; else return size;
01453                 if (i19.valid) size++; else return size;
01454                 if (i20.valid) size++; else return size;
01455                 if (i21.valid) size++; else return size;
01456                 if (i22.valid) size++; else return size;
01457                 if (i23.valid) size++; else return size;
01458                 if (i24.valid) size++; else return size;
01459                 if (i25.valid) size++; else return size;
01460                 if (i26.valid) size++; else return size;
01461                 if (i27.valid) size++; else return size;
01462                 if (i28.valid) size++; else return size;
01463                 if (i29.valid) size++; else return size;
01464                 if (i30.valid) size++; else return size;
01465                 if (i31.valid) size++; else return size;
01466                 
01467                 return size;
01468         }
01469 
01470 public:
01471         NumericalArray (InitialNumber const &i00,
01472                                     InitialNumber const &i01,
01473                                     InitialNumber const &i02,
01474                                     InitialNumber const &i03,
01475                                     InitialNumber const &i04,
01476                                     InitialNumber const &i05,
01477                                     InitialNumber const &i06,
01478                                     InitialNumber const &i07,
01479                                     InitialNumber const &i08,
01480                                     InitialNumber const &i09,
01481                                     InitialNumber const &i10,
01482                                     InitialNumber const &i11,
01483                                     InitialNumber const &i12,
01484                                     InitialNumber const &i13,
01485                                     InitialNumber const &i14,
01486                                     InitialNumber const &i15,
01487                                     InitialNumber const &i16,
01488                                     InitialNumber const &i17 = InitialNumber(),
01489                                     InitialNumber const &i18 = InitialNumber(),
01490                                     InitialNumber const &i19 = InitialNumber(),
01491                                     InitialNumber const &i20 = InitialNumber(),
01492                                     InitialNumber const &i21 = InitialNumber(),
01493                                     InitialNumber const &i22 = InitialNumber(),
01494                                     InitialNumber const &i23 = InitialNumber(),
01495                                     InitialNumber const &i24 = InitialNumber(),
01496                                     InitialNumber const &i25 = InitialNumber(),
01497                                     InitialNumber const &i26 = InitialNumber(),
01498                                     InitialNumber const &i27 = InitialNumber(),
01499                                     InitialNumber const &i28 = InitialNumber(),
01500                                     InitialNumber const &i29 = InitialNumber(),
01501                                     InitialNumber const &i30 = InitialNumber(),
01502                                     InitialNumber const &i31 = InitialNumber()) throw()
01503         :       Base (countValidInitialisers (     i17, i18, i19, i20, i21, i22, i23,
01504                                       i24, i25, i26, i27, i28, i29, i30, i31), 
01505                                                                       false)
01506         {
01507                 NumericalType *thisArray = this->getArray();
01508                 
01509                 if (i00.valid) thisArray[ 0] = i00.value; else return;
01510                 if (i01.valid) thisArray[ 1] = i01.value; else return;
01511                 if (i02.valid) thisArray[ 2] = i02.value; else return;
01512                 if (i03.valid) thisArray[ 3] = i03.value; else return;
01513                 if (i04.valid) thisArray[ 4] = i04.value; else return;
01514                 if (i05.valid) thisArray[ 5] = i05.value; else return;
01515                 if (i06.valid) thisArray[ 6] = i06.value; else return;
01516                 if (i07.valid) thisArray[ 7] = i07.value; else return;
01517                 if (i08.valid) thisArray[ 8] = i08.value; else return;
01518                 if (i09.valid) thisArray[ 9] = i09.value; else return;
01519                 if (i10.valid) thisArray[10] = i10.value; else return;
01520                 if (i11.valid) thisArray[11] = i11.value; else return;
01521                 if (i12.valid) thisArray[12] = i12.value; else return;
01522                 if (i13.valid) thisArray[13] = i13.value; else return;
01523                 if (i14.valid) thisArray[14] = i14.value; else return;
01524                 if (i15.valid) thisArray[15] = i15.value; else return;
01525                 if (i16.valid) thisArray[16] = i16.value; else return;
01526                 if (i17.valid) thisArray[17] = i17.value; else return;
01527                 if (i18.valid) thisArray[18] = i18.value; else return;
01528                 if (i19.valid) thisArray[19] = i19.value; else return;
01529                 if (i20.valid) thisArray[20] = i20.value; else return;
01530                 if (i21.valid) thisArray[21] = i21.value; else return;
01531                 if (i22.valid) thisArray[22] = i22.value; else return;
01532                 if (i23.valid) thisArray[23] = i23.value; else return;
01533                 if (i24.valid) thisArray[24] = i24.value; else return;
01534                 if (i25.valid) thisArray[25] = i25.value; else return;
01535                 if (i26.valid) thisArray[26] = i26.value; else return;
01536                 if (i27.valid) thisArray[27] = i27.value; else return;
01537                 if (i28.valid) thisArray[28] = i28.value; else return;
01538                 if (i29.valid) thisArray[29] = i29.value; else return;
01539                 if (i30.valid) thisArray[30] = i30.value; else return;
01540                 if (i31.valid) thisArray[31] = i31.value; else return;
01541         }
01542                 
01543         NumericalArray& operator= (ObjectArray<NumericalType> const& other) throw()
01544         {
01545                 return operator= (static_cast<NumericalArray const&> (other) );
01546         }
01547     
01548     template<PLONK_BINARYOPFUNCTION(NumericalType, op)>
01549     NumericalArray binary (NumericalArray const& rightOperand) const throw() 
01550     {
01551         const unsigned int leftSize = this->size();                                                                                                             
01552         if (leftSize == 0) 
01553             return rightOperand;        
01554         
01555         const unsigned int rightSize = rightOperand.size();                                                                                             
01556         if (rightSize == 0) 
01557             return *this;                                                                                                                               
01558         
01559         const bool eitherNullTerminated = this->isNullTerminated() || rightOperand.isNullTerminated();  
01560         
01561         const unsigned int leftLength = this->length();                                                                                                 
01562         const unsigned int rightLength = rightOperand.length();                                                                                 
01563         const unsigned int newLength = leftLength > rightLength ? leftLength : rightLength;                             
01564         const unsigned int newSize = leftSize > rightSize ? leftSize : rightSize;       
01565         
01566         const NumericalType *leftArray = this->getArray();                                                                                              
01567         const NumericalType *rightArray = rightOperand.getArray();
01568         
01569         NumericalArray result (NumericalArraySpec (newSize, false), eitherNullTerminated);      
01570         NumericalType *resultArray = result.getArray();
01571         
01572         if (eitherNullTerminated) 
01573             resultArray[newLength] = 0;                                                                                 
01574         
01575         unsigned int i;
01576         
01577         if (leftLength == rightLength)
01578         {
01579             NumericalArrayBinaryOp<NumericalType,op>::calcNN (resultArray, leftArray, rightArray, newLength);            
01580         }
01581         else if (rightLength == 1)
01582         {
01583             NumericalArrayBinaryOp<NumericalType,op>::calcN1 (resultArray, leftArray, rightArray[0], newLength);            
01584         }
01585         else if (leftLength == 1)
01586         {
01587             NumericalArrayBinaryOp<NumericalType,op>::calc1N (resultArray, leftArray[0], rightArray, newLength);            
01588         }
01589         else
01590         {
01591             for (i = 0; i < newLength; ++i)     
01592                 resultArray[i] = op (leftArray[i % leftLength], rightArray[i % rightLength]);                   
01593         }
01594         
01595         return result;        
01596     }    
01597         
01598     template<PLONK_UNARYOPFUNCTION(NumericalType, op)>
01599     NumericalArray unary() const throw() 
01600     {
01601         const int newSize = this->size();
01602         const int newLength = this->length();
01603         
01604         if (newSize == 0) 
01605             return *this;
01606         
01607         const bool needsNull = this->isNullTerminated();
01608         NumericalArray result (NumericalArraySpec (newSize, false), needsNull);
01609         const NumericalType *thisArray = this->getArray();
01610         NumericalType *resultArray = result.getArray();
01611         
01612         NumericalArrayUnaryOp<NumericalType,op>::calc (resultArray, thisArray, newLength); // was newSize but ure that was a bug
01613         
01614         if (needsNull) 
01615             resultArray[newLength] = 0;
01616         
01617         return result;
01618     }    
01619     
01620     PLONK_BINARYOPS(NumericalArray);
01621     PLONK_UNARYOPS(NumericalArray);
01622         
01623         inline void zero() throw()
01624         {
01625                 NumericalType *array = this->getArray();
01626                 
01627                 if ((array != 0) && (this->size() > 0))
01628             zeroData (array, this->size());            
01629         }
01630     
01631     NumericalType findMean() const throw()
01632     {
01633                 const NumericalType *array = this->getArray();
01634                 NumericalType result (0);
01635         
01636         const int length = this->length();
01637         
01638         if ((array != 0) && (length > 0))
01639         {            
01640             for (int i = 0; i < length; ++i)
01641                 result += array[i];
01642                 
01643             result /= NumericalType (length);
01644         }
01645         
01646         return result;
01647     }
01648 
01649     NumericalType findMeanAbs() const throw()
01650     {
01651         const NumericalType *array = this->getArray();
01652         NumericalType result (0);
01653         
01654         const int length = this->length();
01655         
01656         if ((array != 0) && (length > 0))
01657         {                            
01658             for (int i = 0; i < length; ++i)
01659                 result += UnaryOpFunctionsType::abs (array[i]);
01660                     
01661             result /= NumericalType (length);
01662         }
01663         
01664         return result;
01665     }
01666 
01667     NumericalType findRMS() const throw()
01668     {
01669         const NumericalType *array = this->getArray();
01670         NumericalType result (0);
01671         
01672         const int length = this->length();
01673 
01674         if ((array != 0) && (length > 0))
01675         {
01676             for (int i = 0; i < length; ++i)
01677                 result += UnaryOpFunctionsType::squared (array[i]);
01678                     
01679             result = UnaryOpFunctionsType::sqrt (result) / NumericalType (length);
01680         }
01681         
01682         return result;        
01683     }
01684 
01685     NumericalType findMaximum() const throw()
01686     {
01687                 const NumericalType *array = this->getArray();
01688                 NumericalType result (0);
01689         
01690                 if ((array != 0) && (this->size() > 0))
01691                 {
01692                         const int length = this->length();
01693                         
01694             if (length > 0)
01695                 result = array[0];
01696             
01697             for (int i = 1; i < length; ++i)
01698                 result = BinaryOpFunctionsType::max (result, array[i]);
01699                 }               
01700         
01701         return result;
01702     }
01703     
01704     NumericalType findMaximumAbs() const throw()
01705     {
01706                 const NumericalType *array = this->getArray();
01707                 NumericalType result (0);
01708         
01709                 if ((array != 0) && (this->size() > 0))
01710                 {
01711                         const int length = this->length();
01712                         
01713             if (length > 0)
01714                 result = array[0];
01715             
01716             for (int i = 1; i < length; ++i)
01717                 result = BinaryOpFunctionsType::max (result, UnaryOpFunctionsType::abs (array[i]));
01718                 }               
01719         
01720         return result;
01721     }
01722 
01723     
01724     NumericalType findMinimum() const throw()
01725     {
01726                 const NumericalType *array = this->getArray();
01727                 NumericalType result (0);
01728         
01729                 if ((array != 0) && (this->size() > 0))
01730                 {
01731                         const int length = this->length();
01732                         
01733             if (length > 0)
01734                 result = array[0];
01735             
01736             for (int i = 1; i < length; ++i)
01737                 result = BinaryOpFunctionsType::min (result, array[i]);
01738                 }               
01739         
01740         return result;
01741     }    
01742     
01743     int indexOfMaximum() const throw()
01744     {
01745                 const NumericalType *array = this->getArray();
01746                 NumericalType currentMax (0);
01747         int index = -1;
01748         
01749                 if ((array != 0) && (this->size() > 0))
01750                 {
01751                         const int length = this->length();
01752                         
01753             if (length > 0)
01754             {
01755                 index = 0;
01756                 currentMax = array[0];
01757             }
01758             
01759             for (int i = 1; i < length; ++i)
01760             {
01761                 if (array[i] > currentMax)
01762                 {
01763                     currentMax = array[i];
01764                     index = i;
01765                 }
01766             }            
01767                 }               
01768         
01769         return index;
01770     }
01771     
01772     int indexOfMinimum() const throw()
01773     {
01774                 const NumericalType *array = this->getArray();
01775                 NumericalType currentMin (0);
01776         int index = -1;
01777         
01778                 if ((array != 0) && (this->size() > 0))
01779                 {
01780                         const int length = this->length();
01781                         
01782             if (length > 0)
01783             {
01784                 index = 0;
01785                 currentMin = array[0];
01786             }
01787             
01788             for (int i = 1; i < length; ++i)
01789             {
01790                 if (array[i] < currentMin)
01791                 {
01792                     currentMin = array[i];
01793                     index = i;
01794                 }
01795             }            
01796                 }               
01797         
01798         return index;
01799     }
01800     
01801     NumericalArray& normalise() throw()
01802     {
01803         NumericalType *array = this->getArray();
01804                 
01805                 if ((array != 0) && (this->size() > 0))
01806                 {
01807             const NumericalType maximum = this->findMaximumAbs();
01808             
01809             if (maximum > NumericalType (0))
01810             {
01811                 const NumericalType factor = UnaryOpFunctionsType::reciprocal (maximum);
01812                 const int size = this->size();
01813                 
01814                 for (int i = 0; i < size; ++i)
01815                     array[i] *= factor;
01816             }
01817                 }               
01818         
01819         return *this;
01820     }
01821         
01822         bool contains (const NumericalType* items) const throw()
01823         {
01824                 plonk_assert (items != 0);
01825                 return Base::contains (NumericalArray (items));
01826         }
01827         
01828         int indexOf (NumericalType const& itemToSearchFor, const int startIndex = 0) const throw()
01829         {
01830                 return Base::indexOf (itemToSearchFor, startIndex);
01831         }
01832         
01833         int indexOf (NumericalArray const& itemsToSearchFor, const int startIndex = 0) const throw()
01834         {
01835                 return Base::indexOf (itemsToSearchFor, startIndex);
01836         }
01837         
01838         int indexOfAny (NumericalArray const& itemsToSearchFor, const int startIndex = 0) const throw()
01839         {
01840                 return Base::indexOfAny (itemsToSearchFor, startIndex);
01841         }
01842         
01844         int indexOf (const NumericalType* items, const int startIndex = 0) const throw()
01845         {
01846                 plonk_assert (items != 0);
01847                 plonk_assert (startIndex >= 0);
01848                 return Base::indexOf (NumericalArray (items), startIndex);
01849         }
01850         
01852         int indexOfAny (const NumericalType *items, const int startIndex = 0) const throw()
01853         {
01854                 plonk_assert (items != 0);
01855                 plonk_assert (startIndex >= 0);
01856                 return Base::indexOfAny (NumericalArray (items), startIndex);
01857         }
01858         
01859         Base replace (NumericalArray const& find, const NumericalType *substitute) const throw()
01860         {
01861                 plonk_assert (substitute != 0);
01862                 return Base::replace (find, NumericalArray (substitute));
01863         }
01864         
01865         Base replace (const NumericalType *find, NumericalArray const& substitute) const throw()
01866         {
01867                 plonk_assert (find != 0);
01868                 return Base::replace(NumericalArray (find), substitute);
01869         }
01870         
01871         Base replace (const NumericalType *find, const NumericalType *substitute) const throw()
01872         {
01873                 plonk_assert (find != 0);
01874                 plonk_assert (substitute != 0);
01875                 return Base::replace (NumericalArray (find), NumericalArray (substitute));
01876         }
01877         
01878         ObjectArray2DType split (const NumericalType *delimiters) const throw()
01879         {
01880                 plonk_assert (delimiters != 0);
01881                 return Base::split (NumericalArray(delimiters));
01882         }
01883 
01884         ObjectArray2DType splitSequence (const NumericalType *delimitingSequence) const throw()
01885         {
01886                 plonk_assert (delimitingSequence != 0);
01887                 return Base::splitSequence (NumericalArray (delimitingSequence));
01888         }       
01889         
01890         void print (const char *prefix = 0, const bool oneLine = false) const throw()
01891         {
01892 #if !PLONK_ANDROID
01893         int i;
01894         
01895                 if (oneLine)
01896                 {
01897                         if (prefix) std::cout << prefix << ": ";
01898                         
01899                         for (i = 0; i < this->size(); i++)
01900                         {
01901                                 std::cout << this->at (i) << " ";
01902                         }
01903                         
01904                         std::cout << std::endl;
01905                 }
01906                 else
01907                 {
01908                         for (i = 0; i < this->size(); i++)
01909                         {
01910                                 if (prefix) std::cout << prefix;
01911                                 
01912                                 std::cout << "[" << i << "] = " << this->at (i) << std::endl;
01913                         }
01914                 }
01915 #endif
01916         }
01917     
01918     int getTypeCode() const throw()
01919     {
01920         return TypeUtility<NumericalArray>::getTypeCode();
01921     }
01922     
01923     int getValueTypeCode() const throw()
01924     {
01925         return TypeUtility<NumericalType>::getTypeCode();
01926     }
01927     
01928     PLONK_OBJECTARROWOPERATOR(NumericalArray);
01929 
01930 };
01931 
01932 PLONK_BINARYOPGLOBALS_TEMPLATE(NumericalArray,NumericalType); // declares global functions with the same name as the binary operators
01933 PLONK_UNARYOPGLOBALS_TEMPLATE(NumericalArray,NumericalType);  // declares global functions with the same name as the unary operators
01934 
01935 
01936 
01937 #endif // PLONK_NUMERICALARRAY_H
 All Classes Functions Typedefs Enumerations Enumerator Properties