![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
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