PARP Research Group University of Murcia, Spain


src/qvmath/qvtensorindexator.h

Go to the documentation of this file.
00001 /*
00002  *      Copyright (C) 2007, 2008, 2009. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00024 
00025 #ifndef QVTENSORINDEXATOR_H
00026 #define QVTENSORINDEXATOR_H
00027 
00028 #include <qvmath/qvtensorindex.h>
00029 #include <iostream>
00030 
00031 #ifndef DOXYGEN_IGNORE_THIS
00032 class QVTensorIndexator
00033         {
00034         public:
00035                 int matrixIndex;
00036                 QVector <int> indexes, steps, dims;
00037 
00038                 QVTensorIndexator(const QVTensorIndexator &indexator):
00039                         matrixIndex(indexator.matrixIndex), indexes(indexator.indexes), steps(indexator.steps), dims(indexator.dims)
00040                         {};
00041 
00042                 QVTensorIndexator(const QVector<int> &dims):
00043                         matrixIndex(0), indexes(dims.size(),0), steps(dims.size()), dims(dims)
00044                         {
00045                         for (int i = dims.size() -1, accum = 1; i>=0; accum *= dims[i--])
00046                                 steps[i] = accum;
00047                         }
00048 
00049                 const QVector<int> getIndexes()         const   { return indexes; }
00050                 const int getIndex(const int position)  const   { return indexes[position]; }
00051                 const int getStep(const int position)   const   { return steps[position]; }
00052                 const int getDim(const int position)    const   { return dims[position]; }
00053                 const int getMatrixIndex()              const   { return matrixIndex; }
00054                 const int getNumberOfDimensions()       const   { Q_ASSERT(indexes.size() == steps.size() && steps.size() == dims.size()); return dims.size(); }
00055 
00056                 void swapIndexes(const int position1, const int position2)
00057                         {
00058                         if (position1 == position2)
00059                                 return;
00060 
00061                         const int temp1 = indexes[position1];
00062                         indexes[position1] = indexes[position2];
00063                         indexes[position2] = temp1;
00064 
00065                         const int temp2 = steps[position1];
00066                         steps[position1] = steps[position2];
00067                         steps[position2] = temp2;
00068 
00069                         const int temp3 = dims[position1];
00070                         dims[position1] = dims[position2];
00071                         dims[position2] = temp3;
00072                         }
00073 
00074                 void setIndex(const int position, const int value)
00075                         {
00076                         const int oldValue = indexes[position];
00077                         indexes[position] = value;
00078                         matrixIndex += (value - oldValue)*steps[position];
00079                         }
00080 
00081                 void setMatrixIndex(const int matIndex)
00082                         {
00083                         indexes[0] = matIndex / steps[0];
00084                         for (int i = 1; i < indexes.size(); i++)
00085                                 indexes[i] = (matIndex/steps[i])%(steps[i-1]/steps[i]);
00086                         }
00087         };
00088 
00089 class QVTensorIterator
00090         {
00091         private:
00092                 QVector< int > numIndexes, indexes;
00093                 QVector < QVector < int > > elementIndexes;
00094                 int maxPartialIndex;
00095                 QVTensorIndexator indexator;
00096 
00097         public:
00098                 QVTensorIterator(const QVector<int> &dims, const QList<int> orderList = QList<int>()):
00099                         numIndexes(dims), indexes(dims.size(),0), elementIndexes(dims.size()), maxPartialIndex(dims.size()-1), indexator(dims)
00100                         { Q_UNUSED(orderList); }
00101 
00102                 QVTensorIterator(const QVTensorIndexator &indexator, const int maxPartialIndex):
00103                         numIndexes(indexator.dims), indexes(indexator.dims.size(),0), elementIndexes(indexator.dims.size()),
00104                         maxPartialIndex(maxPartialIndex), indexator(indexator)
00105                         { }
00106 
00107                 QVTensorIterator(const QVector<int> &dims, const QVector<int> &indexId, const QVTensorIndexValues &indexRangeList):
00108                         numIndexes(dims), indexes(dims.size(),0), elementIndexes(dims.size()), maxPartialIndex(dims.size()-1), indexator(dims)
00109                         {
00110                         const int numDims = dims.size();
00111                         const QMap<int, QVector<int> > map = indexRangeList.getIndexesValues();
00112 
00113                         for (int i = 0; i < numDims; i++)
00114                                 {
00115                                 elementIndexes[i] = map[indexId[i]];
00116 
00117                                 const int size = elementIndexes[i].size();
00118                                 if (size > 0)
00119                                         {
00120                                         numIndexes[i] = -size;
00121                                         maxPartialIndex = i;
00122                                         }
00123                                 }
00124 
00125                         for (int i = 0; i < numDims; i++)
00126                                 indexator.setIndex(i,(numIndexes[i] >= 1)?indexes[i]:elementIndexes[i][indexes[i]]);
00127                         }
00128 
00129                 const int getVectorIndex()                              const   { return indexator.matrixIndex; }
00130                 const int getVectorSize()                               const   { return indexator.steps[maxPartialIndex]; }
00131                 const QVector<int> getIndexes()                         const   { return indexator.getIndexes(); }
00132                 const int getIndex(const int position)                  const   { return indexator.getIndex(position); }
00133                 const int numElementsDimension(const int indexPos)      const   { return ABS(numIndexes[indexPos]); }
00134 
00135                 bool nextVector()
00136                         {
00137                         int actualIndex = maxPartialIndex+1;
00138 
00139                         while(--actualIndex >= 0)
00140                                 if (++indexes[actualIndex] < ABS(numIndexes[actualIndex]))
00141                                         {
00142                                         const int newIndexValue1 = (numIndexes[actualIndex] >= 1)?indexes[actualIndex]:elementIndexes[actualIndex][indexes[actualIndex]];
00143                                         indexator.setIndex(actualIndex, newIndexValue1);
00144                                         break;
00145                                         }
00146                                 else    {
00147                                         indexes[actualIndex] = 0;
00148                                         const int newIndexValue2 = (numIndexes[actualIndex] >= 1)?indexes[actualIndex]:elementIndexes[actualIndex][indexes[actualIndex]];
00149                                         indexator.setIndex(actualIndex, newIndexValue2);
00150                                         }
00151 
00152                         if (actualIndex < 0)
00153                                 return false;
00154 
00155                         return true;
00156                         }
00157         };
00158 
00159 #endif
00160 
00161 #endif



QVision framework. PARP research group, copyright 2007, 2008.