/* * Copyright (c) 2002-2006 Samit Basu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ //Contains routines to assist in manipulations of numeric arrays - used to //be part of the Array class, but have split them out here due to unwieldiness #include "NumericArray.hpp" #include "Array.hpp" #include "FunctionDef.hpp" #include "Dimensions.hpp" // We want to get an n-dimimensional subset of an array // b = a(v1,v2,v3) // We want to generate the sequence // 0 0 0 // 0 0 1 // 0 0 n-1 // 0 1 0 // 0 1 1 // 0 1 2 // We can either compute this using the module algorithm // or incrementally. So if we have an input of size // N x P x M, then the ith element // // The following code is a reasonable compromise of tightness/readibility. // However, a benchmark shows that MATLAB is roughly 12% faster in a few // instances. I'm open to suggestions on how to squeeze that 12% out of this // code in a clean (i.e., cross-platform) way. // // This is the generic version (no special cases here). template void getNDimSubsetNumericNoColonReal(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void setNDimSubsetNumericNoColonReal(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void getNDimSubsetNumericNoColonBurst(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int burstLen) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void setNDimSubsetNumericNoColonBurst(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int burstLen, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } // // This is the first colon version, i.e. A(:,...) - the // first colon means a rapid block copy can be used instead // of element-at-a-time. template void getNDimSubsetNumericFirstColonReal(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void setNDimSubsetNumericFirstColonReal(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void getNDimSubsetNumericFirstColonBurst(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int burstLen) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void setNDimSubsetNumericFirstColonBurst(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int burstLen, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } // This is a slight optimization - if a colon op is // used, but not in the first index, we save the generation // of the colon array in that index - a small optimization. template void getNDimSubsetNumericAnyColonReal(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } // This is a slight optimization - if a colon op is // used, but not in the first index, we save the generation // of the colon array in that index - a small optimization. template void setNDimSubsetNumericAnyColonReal(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void getNDimSubsetNumericAnyColonBurst(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex, int burstLen) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } template void setNDimSubsetNumericAnyColonBurst(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex, int burstLen, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i= outDims[j]) { ndxptr[j] = 0; ndxptr[j+1]++; } } } } // An optimized case - here, we have the case // A(n1,n2,...nd,:,nd+1,...nm) // We do this using a simple stride/start calculation // The first element we calculate as in the regular case // template void getNDimSubsetNumericSliceReal(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex) { // Calculate the number of output elements int outCount = 1; for (int i=0;i void setNDimSubsetNumericSliceReal(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i void getNDimSubsetNumericSliceBurst(const T *sp, T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex, int burstLen) { // Calculate the number of output elements int outCount = 1; for (int i=0;i void setNDimSubsetNumericSliceBurst(T *sp, const T* destp, int outDims[maxDims], int srcDims[maxDims], constIndexPtr* ndx, int numDims, int colonIndex, int burstLen, int advance) { // Calculate the number of output elements int outCount = 1; for (int i=0;i void getNDimSubsetNumericDispatchBurst(int colonIndex, const T* srcptr, T* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen) { int elCount = 1; for (int i=0;i(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, burstLen); else if (colonIndex == 0) getNDimSubsetNumericFirstColonBurst(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, burstLen); else if (elCount > srcDimsInt[colonIndex]) getNDimSubsetNumericAnyColonBurst(srcptr, destptr,outDimsInt,srcDimsInt, indx, L,colonIndex, burstLen); else getNDimSubsetNumericSliceBurst(srcptr, destptr,outDimsInt,srcDimsInt, indx,L,colonIndex, burstLen); } template void setNDimSubsetNumericDispatchBurst(int colonIndex, T* srcptr, const T* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen, int advance) { int elCount = 1; for (int i=0;i(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, burstLen, advance); else if (colonIndex == 0) setNDimSubsetNumericFirstColonBurst(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, burstLen, advance); else if (elCount > srcDimsInt[colonIndex]) setNDimSubsetNumericAnyColonBurst(srcptr, destptr,outDimsInt,srcDimsInt, indx, L,colonIndex, burstLen, advance); else setNDimSubsetNumericSliceBurst(srcptr, destptr,outDimsInt,srcDimsInt, indx,L,colonIndex, burstLen, advance); } template void getNDimSubsetNumericDispatchReal(int colonIndex, const T* srcptr, T* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L) { int elCount = 1; for (int i=0;i(srcptr, destptr,outDimsInt,srcDimsInt, indx, L); else if (colonIndex == 0) getNDimSubsetNumericFirstColonReal(srcptr, destptr,outDimsInt,srcDimsInt, indx, L); else if (elCount > srcDimsInt[colonIndex]) getNDimSubsetNumericAnyColonReal(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, colonIndex); else getNDimSubsetNumericSliceReal(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, colonIndex); } template void setNDimSubsetNumericDispatchReal(int colonIndex, T* srcptr, const T* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int advance) { int elCount = 1; for (int i=0;i(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, advance); else if (colonIndex == 0) setNDimSubsetNumericFirstColonReal(srcptr, destptr,outDimsInt,srcDimsInt, indx, L, advance); else if (elCount > srcDimsInt[colonIndex]) setNDimSubsetNumericAnyColonReal(srcptr, destptr,outDimsInt,srcDimsInt, indx, L,colonIndex, advance); else setNDimSubsetNumericSliceReal(srcptr, destptr,outDimsInt,srcDimsInt, indx,L,colonIndex, advance); } template void getNDimSubsetNumericDispatchBurst(int colonIndex, const float* srcptr, float* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen); template void getNDimSubsetNumericDispatchBurst(int colonIndex, const double* srcptr, double* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen); template void getNDimSubsetNumericDispatchBurst(int colonIndex, const Array* srcptr, Array* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen); template void getNDimSubsetNumericDispatchReal(int colonIndex, const float* srcptr, float* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); // template void getNDimSubsetNumericDispatchReal(int colonIndex, // const logical* srcptr, // logical* destptr, // int outDimsInt[maxDims], // int srcDimsInt[maxDims], // constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const double* srcptr, double* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const char* srcptr, char* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const int8* srcptr, int8* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const uint8* srcptr, uint8* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const int16* srcptr, int16* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const uint16* srcptr, uint16* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const int32* srcptr, int32* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const uint32* srcptr, uint32* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const int64* srcptr, int64* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const uint64* srcptr, uint64* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const Array* srcptr, Array* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void getNDimSubsetNumericDispatchReal(int colonIndex, const FuncPtr* srcptr, FuncPtr* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L); template void setNDimSubsetNumericDispatchBurst(int colonIndex, float* srcptr, const float* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen,int advance); template void setNDimSubsetNumericDispatchBurst(int colonIndex, double* srcptr, const double* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen,int advance); template void setNDimSubsetNumericDispatchBurst(int colonIndex, Array* srcptr, const Array* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L, int burstLen,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, float* srcptr, const float* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); // template void setNDimSubsetNumericDispatchReal(int colonIndex, // logical* srcptr, // const logical* destptr, // int outDimsInt[maxDims], // int srcDimsInt[maxDims], // constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, double* srcptr, const double* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, char* srcptr, const char* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, int8* srcptr, const int8* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, uint8* srcptr, const uint8* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, int16* srcptr, const int16* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, uint16* srcptr, const uint16* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, int32* srcptr, const int32* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, uint32* srcptr, const uint32* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, int64* srcptr, const int64* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, uint64* srcptr, const uint64* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, Array* srcptr, const Array* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance); template void setNDimSubsetNumericDispatchReal(int colonIndex, FuncPtr* srcptr, const FuncPtr* destptr, int outDimsInt[maxDims], int srcDimsInt[maxDims], constIndexPtr* indx, int L,int advance);