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 <qtensor/qtensorindex.h>
00029
00031 class QTensorIndexator
00032 {
00033 public:
00034 int matrixIndex;
00035 QVector <int> indexes, steps, dims;
00036
00037 QTensorIndexator(const QTensorIndexator &indexator):
00038 matrixIndex(indexator.matrixIndex), indexes(indexator.indexes), steps(indexator.steps), dims(indexator.dims)
00039 {};
00040
00041 QTensorIndexator(const QVector<int> &dims):
00042 dims(dims), matrixIndex(0), indexes(dims.size(),0), steps(dims.size())
00043 {
00044 for (int i = dims.size() -1, accum = 1; i>=0; accum *= dims[i--])
00045 steps[i] = accum;
00046 }
00047
00048 const int getIndex(const int position) const { return indexes[position]; }
00049 const int getStep(const int position) const { return steps[position]; }
00050 const int getDim(const int position) const { return dims[position]; }
00051 const int getMatrixIndex() const { return matrixIndex; }
00052
00053 void swapIndexes(const int position1, const int position2)
00054 {
00055 const int temp1 = indexes[position1];
00056 indexes[position1] = indexes[position2];
00057 indexes[position2] = temp1;
00058
00059 const int temp2 = steps[position1];
00060 steps[position1] = steps[position2];
00061 steps[position2] = temp2;
00062
00063 const int temp3 = dims[position1];
00064 dims[position1] = dims[position2];
00065 dims[position2] = temp3;
00066 }
00067
00068 void setIndex(const int position, const int value)
00069 {
00070 int oldValue = indexes[position];
00071 indexes[position] = value;
00072 matrixIndex += (value - oldValue)*steps[position];
00073 }
00074
00075 void setMatrixIndex(const int matIndex)
00076 {
00077 indexes[0] = matIndex / steps[0];
00078 for (int i = 1; i < indexes.size(); i++)
00079 indexes[i] = (matIndex/steps[i])%(steps[i-1]/steps[i]);
00080 }
00081 };
00082
00083 class QTensorIterator
00084 {
00085 public:
00086
00087 QVector< int > numIndexes, indexes;
00088 QVector < QVector < int > > elementIndexes;
00089 int maxPartialIndex;
00090 QTensorIndexator indexator;
00091
00092 public:
00094
00095 QTensorIterator(const QVector<int> &dims, const QList<int> orderList = QList<int>()):
00096 numIndexes(dims), indexes(dims.size(),0), elementIndexes(dims.size()), maxPartialIndex(dims.size()-1), indexator(dims)
00097 { }
00098
00099 QTensorIterator(const QTensorIndexator &indexator, const int maxPartialIndex):
00100 numIndexes(indexator.dims), indexes(indexator.dims.size(),0), elementIndexes(indexator.dims.size()),
00101 maxPartialIndex(maxPartialIndex), indexator(indexator)
00102 { }
00103
00104 QTensorIterator(const QVector<int> &dims, const QVector<int> &indexId, const QTensorIndexValues &indexRangeList):
00105 numIndexes(dims), indexes(dims.size(),0), elementIndexes(dims.size()), maxPartialIndex(dims.size()-1), indexator(dims)
00106 {
00107 const int numDims = dims.size();
00108 const QMap<int, QVector<int> > map = indexRangeList.getIndexesValues();
00109
00110 for (int i = 0; i < numDims; i++)
00111 {
00112 elementIndexes[i] = map[indexId[i]];
00113 const int size = elementIndexes[i].size();
00114 if (size > 0)
00115 {
00116 numIndexes[i] = -size;
00117 maxPartialIndex = i;
00118 }
00119 }
00120
00121 for (int i = 0; i < numDims; i++)
00122 indexator.setIndex(i,(numIndexes[i] >= 1)?indexes[i]:elementIndexes[i][indexes[i]]);
00123 }
00124
00125 const int getVectorIndex() const { return indexator.matrixIndex; }
00126 const int getVectorSize() const { return indexator.steps[maxPartialIndex]; }
00127 const int getIndex(const int position) const { return indexator.getIndex(position); }
00128 const int numElementsDimension(const int indexPos) const { return ABS(numIndexes[indexPos]); }
00129
00130 bool nextVector()
00131 {
00132 int actualIndex = maxPartialIndex+1;
00133 while(--actualIndex >= 0)
00134 {
00135 indexes[actualIndex]++;
00136 indexator.setIndex(actualIndex, (numIndexes[actualIndex] >= 1)?indexes[actualIndex]:elementIndexes[actualIndex][indexes[actualIndex]]);
00137
00138 if (indexes[actualIndex] < ABS(numIndexes[actualIndex])) break;
00139
00140 indexes[actualIndex] = 0;
00141 indexator.setIndex(actualIndex,(numIndexes[actualIndex] >= 1)?indexes[actualIndex]:elementIndexes[actualIndex][indexes[actualIndex]]);
00142 }
00143
00144 if (actualIndex < 0)
00145 return false;
00146
00147 return true;
00148 }
00149 };
00150
00152 #endif