00001 /* 00002 * Copyright (C) 2007, 2008. 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 QTENSOR_H 00026 #define QTENSOR_H 00027 00028 #include <math.h> 00029 #include <cblas.h> 00030 #include <iostream> 00031 00032 #include <qvdefines.h> 00033 #include <qvmath/qvblasdatabuffer.h> 00034 #include <qvmath/qvtensorindexator.h> 00035 00237 class QVTensor 00238 { 00239 public: 00240 // Constructors 00241 00245 QVTensor(const QVTensor &tensor): dataSize(tensor.dataSize), dims(tensor.dims), indexIds(tensor.indexIds), data(tensor.data) { } 00246 00253 QVTensor(const QVTensorValence &indexList = QVTensorValence()): 00254 dataSize(1), dims(indexList.size()), indexIds(indexList.size()) 00255 { 00256 for (int n = 0; n < indexList.size(); n++) 00257 { 00258 indexIds[n] = indexList.at(n).id; 00259 dataSize *= (dims[n] = indexList.at(n).dim); 00260 } 00261 00262 // In the case of an empty valence, the tensor will be a scalar 00263 data = new QBlasDataBuffer(dataSize); 00264 } 00265 00266 // Operators 00267 00272 bool operator==(const QVTensor &tensor) const { return equals(tensor); }; 00273 00278 bool operator!=(const QVTensor &tensor) const { return !equals(tensor); }; 00279 00284 QVTensor operator*(const QVTensor &tensor) const { return innerProduct(tensor); }; 00285 00290 QVTensor operator+(const QVTensor &tensor) const { return add(tensor); }; 00291 00296 QVTensor operator-(const QVTensor &tensor) const { return substract(tensor); }; 00297 00301 QVTensor operator^(const QVTensor &tensor) const { return outerProduct(tensor); }; 00302 00307 QVTensor operator()(const QVTensorValence &indexList) const { return renameIndexes(indexList); }; 00308 00309 // Operation methods 00310 00315 const int getDataSize() const { return dataSize; } 00316 00320 const double *getReadData() const { return data->getReadData(); } 00321 00325 double *getWriteData() { return data->getWriteData(); } 00326 00331 QVTensorValence getValence() const; 00332 00340 QVTensor slice(const QVTensorIndexValues &indexRangeList) const; 00341 00348 QVTensor transpose(const QVTensorValence &indexList) const; 00349 00355 QVTensor transpose(const QVTensorIndex &i, const QVTensorIndex &j) const; 00356 00361 QVTensor add(const QVTensor &tensor) const; 00362 00367 QVTensor substract(const QVTensor &tensor) const; 00368 00375 QVTensor tensorProduct(const QVTensor &tensor) const; 00376 00382 QVTensor innerProduct(const QVTensor &tensor) const; 00383 00389 QVTensor outerProduct(const QVTensor &tensor) const; 00390 00396 bool equals(const QVTensor &tensor) const; 00397 00404 QVTensor renameIndexes(const QVTensorValence &indexList) const; 00405 00412 QVTensorIndexator getIndexator() { return QVTensorIndexator(dims); }; 00413 00417 double norm2() const; 00418 00423 static QVTensor leviCivita(const int dimension); 00424 00425 #ifndef DOXYGEN_IGNORE_THIS 00426 // These methods won't be documented, but will be available for testing purposes 00427 QVTensor contract() const; 00428 #endif 00429 00430 private: 00431 friend std::ostream& operator << ( std::ostream &os, const QVTensor &tensor ); 00432 00433 // These should be private 00434 QVTensor transpose(const QVector<int> &sorting) const; 00435 QVTensor transpose(const int index1Position, const int index2Position) const; 00436 QVTensor antisymmetrization(const QVTensor &tensor) const; 00437 00438 // Tensor data 00439 int dataSize; 00440 QVector <int> dims; 00441 QVector <int> indexIds; 00442 QSharedDataPointer< QBlasDataBuffer > data; 00443 }; 00444 00445 std::ostream& operator << ( std::ostream &os, const QVTensor &tensor ); 00446 00447 //Q_DECLARE_METATYPE(QVTensor); 00448 00449 #endif