matrix.hpp
Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Mikael Lagerkvist <lagerkvist@gecode.org> 00005 * 00006 * Copyright: 00007 * Mikael Lagerkvist, 2005 00008 * 00009 * Bugfixes provided by: 00010 * Olof Sivertsson <olof@olofsivertsson.com> 00011 * 00012 * Last modified: 00013 * $Date: 2010-05-15 16:19:43 +0200 (Sat, 15 May 2010) $ by $Author: schulte $ 00014 * $Revision: 10954 $ 00015 * 00016 * This file is part of Gecode, the generic constraint 00017 * development environment: 00018 * http://www.gecode.org 00019 * 00020 * Permission is hereby granted, free of charge, to any person obtaining 00021 * a copy of this software and associated documentation files (the 00022 * "Software"), to deal in the Software without restriction, including 00023 * without limitation the rights to use, copy, modify, merge, publish, 00024 * distribute, sublicense, and/or sell copies of the Software, and to 00025 * permit persons to whom the Software is furnished to do so, subject to 00026 * the following conditions: 00027 * 00028 * The above copyright notice and this permission notice shall be 00029 * included in all copies or substantial portions of the Software. 00030 * 00031 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00032 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00033 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00034 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00035 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00036 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00037 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00038 * 00039 */ 00040 00041 #include <algorithm> 00042 00043 namespace Gecode { 00044 00045 template<class A> 00046 inline 00047 Slice<A>::Slice(const Matrix<A>& a, int fc, int tc, int fr, int tr) 00048 : _r(0), _fc(fc), _tc(tc), _fr(fr), _tr(tr) { 00049 if (tc > a.width() || tr > a.height()) 00050 throw MiniModel::ArgumentOutOfRange("Slice::Slice"); 00051 if (fc >= tc || fr >= tr) { 00052 _fc=0; _tc=0; _fr=0; _tr=0; 00053 return; 00054 } 00055 00056 _r = ArgsType((tc-fc)*(tr-fr)); 00057 00058 int i = 0; 00059 for (int h = fr; h < tr; h++) 00060 for (int w = fc; w < tc; w++) 00061 _r[i++] = a(w, h); 00062 } 00063 00064 template<class A> 00065 Slice<A>& 00066 Slice<A>::reverse(void) { 00067 for (int i = 0; i < _r.size()/2; i++) 00068 std::swap(_r[i], _r[_r.size()-i-1]); 00069 return *this; 00070 } 00071 00072 template<class A> 00073 forceinline 00074 Slice<A>::operator ArgsType(void) { 00075 return _r; 00076 } 00077 template<class A> 00078 forceinline 00079 Slice<A>::operator Matrix<typename Slice<A>::ArgsType>(void) { 00080 return Matrix<ArgsType>(_r, _tc-_fc, _tr-_fr); 00081 } 00082 template<class A> 00083 forceinline 00084 Slice<A>::operator const typename Slice<A>::ArgsType(void) const { 00085 return _r; 00086 } 00087 template<class A> 00088 forceinline 00089 Slice<A>::operator const Matrix<typename Slice<A>::ArgsType>(void) const { 00090 return Matrix<ArgsType>(_r, _tc-_fc, _tr-_fr); 00091 } 00092 00093 template<class A> 00094 typename Slice<A>::ArgsType 00095 operator+(const Slice<A>& x, const Slice<A>& y) { 00096 typename Slice<A>::ArgsType xx = x; 00097 typename Slice<A>::ArgsType yy = y; 00098 return xx+yy; 00099 } 00100 00101 template<class A> 00102 typename Slice<A>::ArgsType 00103 operator+(const Slice<A>& x, const typename ArrayTraits<A>::ArgsType& y) { 00104 typename Slice<A>::ArgsType xx = x; 00105 return xx+y; 00106 } 00107 00108 template<class A> 00109 typename Slice<A>::ArgsType 00110 operator+(const typename ArrayTraits<A>::ArgsType& x, const Slice<A>& y) { 00111 typename Slice<A>::ArgsType yy = y; 00112 return x+yy; 00113 } 00114 00115 template<class A> 00116 typename Slice<A>::ArgsType 00117 operator+(const Slice<A>& x, const typename ArrayTraits<A>::ValueType& y) { 00118 typename Slice<A>::ArgsType xx = x; 00119 return xx+y; 00120 } 00121 00122 template<class A> 00123 typename Slice<A>::ArgsType 00124 operator+(const typename ArrayTraits<A>::ValueType& x, const Slice<A>& y) { 00125 typename Slice<A>::ArgsType yy = y; 00126 return x+yy; 00127 } 00128 00129 template<class A> 00130 forceinline 00131 Matrix<A>::Matrix(A a, int w, int h) 00132 : _a(a), _w(w), _h(h) { 00133 if ((_w * _h) != _a.size()) 00134 throw MiniModel::ArgumentSizeMismatch("Matrix::Matrix(A, w, h)"); 00135 } 00136 00137 template<class A> 00138 forceinline 00139 Matrix<A>::Matrix(A a, int n) 00140 : _a(a), _w(n), _h(n) { 00141 if (n*n != _a.size()) 00142 throw MiniModel::ArgumentSizeMismatch("Matrix::Matrix(A, n)"); 00143 } 00144 00145 template<class A> 00146 forceinline int 00147 Matrix<A>::width(void) const { return _w; } 00148 template<class A> 00149 forceinline int 00150 Matrix<A>::height(void) const { return _h; } 00151 template<class A> 00152 inline typename Matrix<A>::ArgsType const 00153 Matrix<A>::get_array(void) const { 00154 return ArgsType(_a); 00155 } 00156 00157 template<class A> 00158 forceinline typename Matrix<A>::ValueType& 00159 Matrix<A>::operator ()(int c, int r) { 00160 if ((c >= _w) || (r >= _h)) 00161 throw MiniModel::ArgumentOutOfRange("Matrix::operator ()"); 00162 return _a[r*_w + c]; 00163 } 00164 00165 template<class A> 00166 forceinline const typename Matrix<A>::ValueType& 00167 Matrix<A>::operator ()(int c, int r) const { 00168 if ((c >= _w) || (r >= _h)) 00169 throw MiniModel::ArgumentOutOfRange("Matrix::operator ()"); 00170 return _a[r*_w + c]; 00171 } 00172 00173 template<class A> 00174 forceinline Slice<A> 00175 Matrix<A>::slice(int fc, int tc, int fr, int tr) const { 00176 return Slice<A>(*this, fc, tc, fr, tr); 00177 } 00178 00179 template<class A> 00180 forceinline Slice<A> 00181 Matrix<A>::row(int r) const { 00182 return slice(0, width(), r, r+1); 00183 } 00184 00185 template<class A> 00186 forceinline Slice<A> 00187 Matrix<A>::col(int c) const { 00188 return slice(c, c+1, 0, height()); 00189 } 00190 00191 template<class Char, class Traits, class A> 00192 std::basic_ostream<Char,Traits>& 00193 operator <<(std::basic_ostream<Char,Traits>& os, const Matrix<A>& m) { 00194 std::basic_ostringstream<Char,Traits> s; 00195 s.copyfmt(os); s.width(0); 00196 for (int i=0; i<m.height(); i++) { 00197 for (int j=0; j<m.width(); j++) { 00198 s << m(j,i) << "\t"; 00199 } 00200 s << std::endl; 00201 } 00202 return os << s.str(); 00203 } 00204 00205 template<class Char, class Traits, class A> 00206 std::basic_ostream<Char,Traits>& 00207 operator <<(std::basic_ostream<Char,Traits>& os, const Slice<A>& s) { 00208 return os << static_cast<typename Slice<A>::ArgsType>(s); 00209 } 00210 00211 forceinline void 00212 element(Home home, const Matrix<IntArgs>& m, IntVar x, IntVar y, 00213 IntVar z, IntConLevel icl) { 00214 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl); 00215 } 00216 forceinline void 00217 element(Home home, const Matrix<IntArgs>& m, IntVar x, IntVar y, 00218 BoolVar z, IntConLevel icl) { 00219 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl); 00220 } 00221 forceinline void 00222 element(Home home, const Matrix<IntVarArgs>& m, IntVar x, IntVar y, 00223 IntVar z, IntConLevel icl) { 00224 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl); 00225 } 00226 forceinline void 00227 element(Home home, const Matrix<BoolVarArgs>& m, IntVar x, IntVar y, 00228 BoolVar z, IntConLevel icl) { 00229 element(home, m.get_array(), x, m.width(), y, m.height(), z, icl); 00230 } 00231 00232 #ifdef GECODE_HAS_SET_VARS 00233 forceinline void 00234 element(Home home, const Matrix<IntSetArgs>& m, IntVar x, IntVar y, 00235 SetVar z) { 00236 element(home, m.get_array(), x, m.width(), y, m.height(), z); 00237 } 00238 forceinline void 00239 element(Home home, const Matrix<SetVarArgs>& m, IntVar x, IntVar y, 00240 SetVar z) { 00241 element(home, m.get_array(), x, m.width(), y, m.height(), z); 00242 } 00243 #endif 00244 00245 } 00246 00247 // STATISTICS: minimodel-any