blitz Version 0.9
|
00001 /*************************************************************************** 00002 * blitz/matsymm.h Declarations for Symmetric matrices 00003 * 00004 * $Id: matsymm.h,v 1.4 2003/12/11 03:44:22 julianc Exp $ 00005 * 00006 * Copyright (C) 1997-2001 Todd Veldhuizen <tveldhui@oonumerics.org> 00007 * 00008 * This program is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU General Public License 00010 * as published by the Free Software Foundation; either version 2 00011 * of the License, or (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * Suggestions: blitz-dev@oonumerics.org 00019 * Bugs: blitz-bugs@oonumerics.org 00020 * 00021 * For more information, please see the Blitz++ Home Page: 00022 * http://oonumerics.org/blitz/ 00023 * 00024 ***************************************************************************/ 00025 00026 #ifndef BZ_MATSYMM_H 00027 #define BZ_MATSYMM_H 00028 00029 #ifndef BZ_MSTRUCT_H 00030 #error <blitz/matsymm.h> must be included via <blitz/mstruct.h> 00031 #endif 00032 00033 BZ_NAMESPACE(blitz) 00034 00035 // Symmetric, lower triangular row major ordering 00036 // [ 0 1 3 6 ] 00037 // [ 1 2 4 7 ] 00038 // [ 3 4 5 8 ] 00039 // [ 6 7 8 9 ] 00040 00041 class SymmetricIterator { 00042 public: 00043 SymmetricIterator(unsigned rows, unsigned cols) 00044 { 00045 BZPRECONDITION(rows == cols); 00046 size_ = rows; 00047 good_ = true; 00048 offset_ = 0; 00049 i_ = 0; 00050 j_ = 0; 00051 } 00052 00053 operator bool() const { return good_; } 00054 00055 void operator++() 00056 { 00057 BZPRECONDITION(good_); 00058 ++offset_; 00059 ++j_; 00060 if (j_ > i_) 00061 { 00062 j_ = 0; 00063 ++i_; 00064 if (i_ == size_) 00065 good_ = false; 00066 } 00067 } 00068 00069 unsigned row() const 00070 { return i_; } 00071 00072 unsigned col() const 00073 { return j_; } 00074 00075 unsigned offset() const 00076 { return offset_; } 00077 00078 protected: 00079 unsigned size_; 00080 bool good_; 00081 unsigned offset_; 00082 unsigned i_, j_; 00083 }; 00084 00085 class Symmetric : public MatrixStructure { 00086 00087 public: 00088 typedef SymmetricIterator T_iterator; 00089 00090 Symmetric() 00091 : size_(0) 00092 { } 00093 00094 Symmetric(unsigned size) 00095 : size_(size) 00096 { } 00097 00098 Symmetric(unsigned rows, unsigned cols) 00099 : size_(rows) 00100 { 00101 BZPRECONDITION(rows == cols); 00102 } 00103 00104 unsigned columns() const 00105 { return size_; } 00106 00107 unsigned coordToOffset(unsigned i, unsigned j) const 00108 { 00109 BZPRECONDITION(inRange(i,j)); 00110 if (i >= j) 00111 return i*(i+1)/2 + j; 00112 else 00113 return j*(j+1)/2 + i; 00114 } 00115 00116 unsigned firstInRow(unsigned i) const 00117 { return 0; } 00118 00119 template<typename T_numtype> 00120 T_numtype get(const T_numtype * restrict data, 00121 unsigned i, unsigned j) const 00122 { 00123 BZPRECONDITION(inRange(i,j)); 00124 return data[coordToOffset(i,j)]; 00125 } 00126 00127 template<typename T_numtype> 00128 T_numtype& get(T_numtype * restrict data, unsigned i, unsigned j) 00129 { 00130 BZPRECONDITION(inRange(i,j)); 00131 return data[coordToOffset(i,j)]; 00132 } 00133 00134 unsigned lastInRow(unsigned i) const 00135 { return i; } 00136 00137 unsigned firstInCol(unsigned j) const 00138 { return j; } 00139 00140 unsigned lastInCol(unsigned j) const 00141 { return size_ - 1; } 00142 00143 bool inRange(unsigned i, unsigned j) const { 00144 return (i < size_) && (j < size_); 00145 } 00146 00147 unsigned numElements() const 00148 { return size_ * (size_ + 1) / 2; } 00149 00150 unsigned rows() const 00151 { return size_; } 00152 00153 void resize(unsigned size) 00154 { 00155 size_ = size; 00156 } 00157 00158 void resize(unsigned rows, unsigned cols) 00159 { 00160 BZPRECONDITION(rows == cols); 00161 size_ = rows; 00162 } 00163 00164 private: 00165 unsigned size_; 00166 }; 00167 00168 BZ_NAMESPACE_END 00169 00170 #endif // BZ_MATSYMM_H 00171