CUV  0.9.201304091348
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
dia_matrix.hpp
Go to the documentation of this file.
1 //*LB*
2 // Copyright (c) 2010, University of Bonn, Institute for Computer Science VI
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 // * Neither the name of the University of Bonn
14 // nor the names of its contributors may be used to endorse or promote
15 // products derived from this software without specific prior written
16 // permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //*LE*
29 
30 
31 
32 
33 
41 #ifndef __SPARSE_MATRIX_HPP__
42 #define __SPARSE_MATRIX_HPP__
43 #include <vector>
44 #include <map>
45 #include <memory>
46 #include <iostream>
47 #include <cuv/basics/tensor.hpp>
48 #include <cuv/tensor_ops/tensor_ops.hpp>
49 #include <cuv/basics/matrix.hpp>
50 #include <cuv/tools/cuv_general.hpp>
51 
52 namespace cuv{
57  template<class __value_type, class __memory_space_type, class __index_type=unsigned int>
58  class dia_matrix
59  : public matrix<__value_type, __index_type>{
60  public:
61  typedef __value_type value_type;
62  typedef const value_type const_value_type;
64  typedef __memory_space_type memory_space_type;
65  typedef typename base_type::index_type index_type;
70  typedef typename vec_type::pointer_type ptr_type;
71  public:
72  int m_num_dia;
73  unsigned int m_stride;
76  std::map<int,index_type> m_dia2off;
77  int m_row_fact;
78  public:
80  dealloc();
81  }
82 
83  dia_matrix()
84  : base_type(0,0),
85  m_vec(0),
86  m_num_dia(0),
87  m_stride(0),
88  m_row_fact(0){}
98  dia_matrix(const index_type& h, const index_type& w, const int& num_dia, const int& stride, int row_fact=1)
99  : base_type(h,w)
100  , m_vec(NULL)
101  , m_num_dia(num_dia)
102  , m_stride(stride)
103  , m_offsets(num_dia)
104  {
107  alloc();
108 
109  }
110  void dealloc()
111  {
112  if(m_vec){
113  delete m_vec;
114  }
115  m_vec = NULL;
116  }
122  std::vector<index_type>
123  shape()const{
124  std::vector<index_type> s(2);
125  s[0]=this->h();
126  s[1]=this->w();
127  return s;
128  }
129  void alloc()
130  {
131  cuvAssert(m_stride >= this->h() || m_stride >= this->w());
132  m_vec = new vec_type(m_stride * m_num_dia);
133  }
134  inline const vec_type& vec()const{ return *m_vec; }
135  inline vec_type& vec() { return *m_vec; }
136  inline const vec_type* vec_ptr()const{ return m_vec; }
137  inline vec_type* vec_ptr() { return m_vec; }
138  inline ptr_type ptr() { return m_vec->ptr(); }
139  inline const ptr_type ptr()const{ return m_vec->ptr(); }
140  inline int num_dia()const{ return m_num_dia; }
141  inline unsigned int stride()const { return m_stride; }
142  inline int row_fact()const{ return m_row_fact; }
143 
144  //*****************************
145  // set/get offsets of diagonals
146  //*****************************
147 
156  template<class T>
157  void set_offsets(T begin, const T& end){
158  int i=0;
159  while(begin!=end)
160  m_offsets[i++]= *begin++;
162  }
170  template<class T>
171  void set_offsets(const std::vector<T>& v){
172  for(unsigned int i=0;i<v.size();i++)
173  m_offsets[i]=v[i];
175  }
182  m_dia2off.clear();
183  for(unsigned int i = 0; i<m_offsets.size(); ++i)
184  m_dia2off[m_offsets[i]] = i;
185  }
193  inline void set_offset(const index_type& idx, const index_type& val){
194  m_offsets[idx] = val;
195  m_dia2off[val] = idx;
196  }
199  inline const_vec_type* get_dia(const int& k)const{
200  typename std::map<int,index_type>::const_iterator it = m_dia2off.find(k);
201  int off = it->second;
202  const index_type i_start = std::max((int)0,-k);
203  const index_type j_start = std::max((int)0, k);
204  const index_type N = std::min(base_type::m_height - i_start, (base_type::m_width - j_start));
205  return new const_vec_type(indices[index_range(0,m_stride)], m_vec->ptr() + off * m_stride);
206  //return new vec_type(N, m_vec->ptr() + off * m_stride + i_start, true);
207  }
210  inline vec_type* get_dia(const int& k){
211  int off = m_dia2off[k];
212  const index_type i_start = std::max((int)0,-k);
213  const index_type j_start = std::max((int)0, k);
214  const index_type N = std::min(base_type::m_height - i_start, (base_type::m_width - j_start));
215  return new vec_type(indices[index_range(0,m_stride)], m_vec->ptr() + off * m_stride);
216  //return new vec_type(N, m_vec->ptr() + off * m_stride + i_start, true);
217  }
218  inline const intvec_type& get_offsets()const{return m_offsets;}
219  inline intvec_type& get_offsets() {return m_offsets;}
220  inline int get_offset(const index_type& idx)const
221  {
222  return m_offsets[idx];
223  }
224 
225  // ******************************
226  // read access
227  // ******************************
228  void set(const index_type& i, const index_type& j, const value_type& val)
229  {
230  int off = (int)j - (int)i/m_row_fact;
231  typename std::map<int,index_type>::const_iterator it = m_dia2off.find(off);
232  if( it == m_dia2off.end() )
233  return;
234  (*m_vec)[it->second * m_stride +i]=val;
235  }
236  value_type operator()(const index_type& i, const index_type& j)const
237  {
238  int off = (int)j - (int)i/m_row_fact;
239  typename std::map<int,index_type>::const_iterator it = m_dia2off.find(off);
240  if( it == m_dia2off.end() )
241  return (value_type) 0;
242  return (*m_vec)[ it->second * m_stride +i ];
243  }
244  bool has(const index_type& i, const index_type& j)const
245  {
246  int off = (int)j - (int)i/m_row_fact;
247  typename std::map<int,index_type>::const_iterator it = m_dia2off.find(off);
248  if( it == m_dia2off.end() )
249  return false;
250  return true;
251  }
259  my_type&
260  operator=(const my_type& o){
261  if(this==&o) return *this;
262  this->dealloc();
263 
264  (base_type&) (*this) = (base_type&) o;
265  m_vec=o.m_vec;
266  m_num_dia = o.m_num_dia;
267  m_stride = o.m_stride;
269  m_offsets = o.m_offsets;
270  m_dia2off = o.m_dia2off;
271 
272  // transfer ownership of memory (!)
273  (const_cast< my_type *>(&o))->m_vec = NULL;
274  return *this;
275  }
276  };
277 }
278 
279 namespace std{
287  template<class V, class T, class I>
288  ostream&
289  operator<<(ostream& o, const cuv::dia_matrix<V,T,I>& w2){
290  cout << "Dia-Matrix: "<<endl;
291  for(I i=0;i<w2.h();i++){
292  for(I j=0;j<w2.w();j++){
293  o << w2(i,j) << " ";
294  }
295  o << endl;
296  }
297  o << endl;
298  return o;
299  }
300 }
301 
302 #endif /* __SPARSE_MATRIX_HPP__ */
303