00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 int getIndex(const int position) const { return indexes[position]; }
00051 int getStep(const int position) const { return steps[position]; }
00052 int getDim(const int position) const { return dims[position]; }
00053 int getMatrixIndex() const { return matrixIndex; }
00054 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 int getVectorIndex() const { return indexator.matrixIndex; }
00130 int getVectorSize() const { return indexator.steps[maxPartialIndex]; }
00131 const QVector<int> getIndexes() const { return indexator.getIndexes(); }
00132 int getIndex(const int position) const { return indexator.getIndex(position); }
00133 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