Generated on Tue May 22 09:40:11 2018 for Gecode by doxygen 1.6.3

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