remove \r
[extl.git] / extl / container / symmetrical_matrix.h
blobab58f076ba8f6218cee250783956b8a87cf6a969
1 /* ///////////////////////////////////////////////////////////////////////
2 * File: symmetrical_matrix.h
4 * Created: 08.12.05
5 * Updated: 08.12.05
7 * Brief: symmetrical_matrix class - compact matrix
9 * [<Home>]
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
13 #ifndef EXTL_CONTAINER_SYMMETRICAL_MATRIX_H
14 #define EXTL_CONTAINER_SYMMETRICAL_MATRIX_H
16 /*!\file symmetrical_matrix.h
17 * \brief symmetrical_matrix class
20 /* ///////////////////////////////////////////////////////////////////////
21 * Includes
23 #include "prefix.h"
24 #include "../memory/buffer.h"
25 #include "matrix_base.h"
27 /* ///////////////////////////////////////////////////////////////////////
28 * ::extl namespace
30 EXTL_BEGIN_NAMESPACE
33 /*!\brief: symmetrical_matrix class - compact matrix
35 * <pre>
36 * using upper triangular matrix
37 * size = n * (n + 1) / 2
39 * 0 0 0 0 0 0
40 * 0 0 0 0 0
41 * 0 0 0 0
42 * 0 0 0
43 * 0 0
44 * 0
46 * </pre>
48 * \param Val The element type
49 * \param Buf The buffer type
51 * \ingroup extl_group_container
53 template< typename_param_k Val
54 #ifdef EXTL_TEMPLATE_CLASS_DEFAULT_ARGUMENT_SUPPORT
55 , typename_param_k Buf = typename_type_def_k buffer_selector<Val>::buffer_type
56 #else
57 , typename_param_k Buf
58 #endif
60 class symmetrical_matrix
61 : public matrix_base < symmetrical_matrix<Val, Buf>
62 , Buf
65 private:
66 typedef matrix_base < symmetrical_matrix<Val, Buf>
67 , Buf
68 > base_type;
70 /// \name Types
71 /// @{
72 public:
73 typedef symmetrical_matrix class_type;
74 typedef typename_type_k base_type::buffer_type buffer_type;
75 typedef typename_type_k base_type::allocator_type allocator_type;
76 typedef typename_type_k base_type::value_type value_type;
77 typedef typename_type_k base_type::pointer pointer;
78 typedef typename_type_k base_type::const_pointer const_pointer;
79 typedef typename_type_k base_type::reference reference;
80 typedef typename_type_k base_type::const_reference const_reference;
81 typedef typename_type_k base_type::iterator iterator;
82 typedef typename_type_k base_type::const_iterator const_iterator;
83 typedef typename_type_k base_type::reverse_iterator reverse_iterator;
84 typedef typename_type_k base_type::const_reverse_iterator const_reverse_iterator;
85 typedef typename_type_k base_type::size_type size_type;
86 typedef typename_type_k base_type::bool_type bool_type;
87 typedef typename_type_k base_type::difference_type difference_type;
88 typedef typename_type_k base_type::int_type int_type;
89 typedef typename_type_k base_type::index_type index_type;
90 class const_reduced_dimension_type
92 private:
93 const_pointer m_p;
94 index_type m_i;
95 size_type m_dim;
97 public:
98 const_reduced_dimension_type(const_pointer p, index_type i, size_type dim)
99 : m_p(p)
100 , m_i(i)
101 , m_dim(dim)
103 public:
104 const_reference operator[](index_type j) const
106 return at(j);
108 const_reference at(index_type j) const
110 EXTL_ASSERT(NULL != m_p);
111 EXTL_ASSERT(j < m_dim);
112 EXTL_ASSERT(m_i < m_dim);
113 return (m_i < j)? m_p[m_i * (m_dim * 2 + 1 - m_i) / 2 + j - m_i]
114 : m_p[j * (m_dim * 2 + 1 - j) / 2 + m_i - j];
117 class reduced_dimension_type
119 private:
120 pointer m_p;
121 index_type m_i;
122 size_type m_dim;
124 public:
125 reduced_dimension_type(pointer p, index_type i, size_type dim)
126 : m_p(p)
127 , m_i(i)
128 , m_dim(dim)
130 public:
131 reference operator[](index_type j)
133 return at(j);
135 reference at(index_type j)
137 EXTL_ASSERT(NULL != m_p);
138 EXTL_ASSERT(j < m_dim);
139 EXTL_ASSERT(m_i < m_dim);
140 return (m_i < j)? m_p[m_i * (m_dim * 2 + 1 - m_i) / 2 + j - m_i]
141 : m_p[j * (m_dim * 2 + 1 - j) / 2 + m_i - j];
144 /// @}
146 /// \name Constructors
147 /// @{
148 public:
149 symmetrical_matrix()
150 : base_type()
153 symmetrical_matrix(class_type const& rhs)
154 : base_type(rhs)
157 explicit_k symmetrical_matrix(index_type d0, index_type /*d1*/ = 0)
158 : base_type(d0, d0)
160 this->buffer().resize((d0 * (d0 + 1)) >> 1);
162 symmetrical_matrix(const_reference value, index_type d0, index_type /*d1*/ = 0)
163 : base_type(value, d0, d0)
165 this->buffer().resize((d0 * (d0 + 1)) >> 1);
168 /// @}
170 /// \name Attributes
171 /// @{
172 public:
173 size_type dim0() const { return dim1(); }
174 size_type dim1() const { return static_cast<base_type const&>(*this).dim1(); }
175 size_type dim() const { return dim1(); }
176 size_type size() const { return dim0() * dim0(); }
177 /// @}
179 /// \name Accessors
180 /// @{
181 public:
182 reduced_dimension_type at(index_type i0);
183 const_reduced_dimension_type at(index_type i0) const;
185 reduced_dimension_type at_unchecked(index_type i0);
186 const_reduced_dimension_type at_unchecked(index_type i0) const;
188 reduced_dimension_type operator[](index_type i0) { return at_unchecked(i0); }
189 const_reduced_dimension_type operator[](index_type i0) const { return at_unchecked(i0); }
191 reference at(index_type i0, index_type i1);
192 const_reference at(index_type i0, index_type i1) const;
194 reference at_unchecked(index_type i0, index_type i1);
195 const_reference at_unchecked(index_type i0, index_type i1) const;
197 /// @}
199 /// \name Operators
200 /// @{
201 public:
202 class_type& operator=(class_type const& rhs) { return base_type::operator=(rhs); }
203 class_type& operator=(const_reference value) { return base_type::operator=(value); }
204 /// @}
209 /* /////////////////////////////////////////////////////////////////////////
210 * Implemention
212 // at_unchecked(i0, i1)
213 template< typename_param_k Val
214 , typename_param_k Buf
216 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
217 const_reference symmetrical_matrix<Val, Buf>::at_unchecked(index_type i0, index_type i1) const
219 /* matrix[i][j]
220 * buffer[i * (2 * n + 1 - i) / 2 + j - i]
222 EXTL_ASSERT(this->is_valid());
223 EXTL_ASSERT(NULL != this->data());
224 EXTL_ASSERT(i0 < dim());
225 EXTL_ASSERT(i1 < dim());
226 return i0 < i1? this->data()[i0 * (dim() * 2 + 1 - i0) / 2 + i1 - i0]
227 : this->data()[i1 * (dim() * 2 + 1 - i1) / 2 + i0 - i1];
229 template< typename_param_k Val
230 , typename_param_k Buf
232 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
233 reference symmetrical_matrix<Val, Buf>::at_unchecked(index_type i0, index_type i1)
235 return const_cast<reference>(static_cast<class_type const&>(*this).at_unchecked(i0, i1));
238 // at(i0, i1)
239 template< typename_param_k Val
240 , typename_param_k Buf
242 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
243 reference symmetrical_matrix<Val, Buf>::at(index_type i0, index_type i1)
245 return const_cast<reference>(static_cast<class_type const&>(*this).at(i0, i1));
247 template< typename_param_k Val
248 , typename_param_k Buf
250 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
251 const_reference symmetrical_matrix<Val, Buf>::at(index_type i0, index_type i1) const
253 EXTL_ASSERT_THROW(i0 < dim() && i1 < dim(), index_error("out of range"));
254 return at_unchecked(i0, i1);
257 // at_unchecked(i0)
258 template< typename_param_k Val
259 , typename_param_k Buf
261 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
262 reduced_dimension_type symmetrical_matrix<Val, Buf>::at_unchecked(index_type i0)
264 EXTL_ASSERT(this->is_valid());
265 EXTL_ASSERT(NULL != this->data());
266 EXTL_ASSERT(i0 < dim());
267 return reduced_dimension_type(this->data(), i0, dim());
269 template< typename_param_k Val
270 , typename_param_k Buf
272 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
273 const_reduced_dimension_type symmetrical_matrix<Val, Buf>::at_unchecked(index_type i0) const
275 EXTL_ASSERT(this->is_valid());
276 EXTL_ASSERT(NULL != this->data());
277 EXTL_ASSERT(i0 < dim());
278 return const_reduced_dimension_type(this->data(), i0, dim());
281 // at(i0)
282 template< typename_param_k Val
283 , typename_param_k Buf
285 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
286 reduced_dimension_type symmetrical_matrix<Val, Buf>::at(index_type i0)
288 EXTL_ASSERT_THROW(i0 < dim(), index_error("out of range"));
289 return at_unchecked(i0);
291 template< typename_param_k Val
292 , typename_param_k Buf
294 inline typename_type_ret_k symmetrical_matrix<Val, Buf>::
295 const_reduced_dimension_type symmetrical_matrix<Val, Buf>::at(index_type i0) const
297 EXTL_ASSERT_THROW(i0 < dim(), index_error("out of range"));
298 return at_unchecked(i0);
300 /* ///////////////////////////////////////////////////////////////////////
301 * ::extl namespace
303 EXTL_END_NAMESPACE
305 /* //////////////////////////////////////////////////////////////////// */
306 #endif /* EXTL_CONTAINER_SYMMETRICAL_MATRIX_H */
307 /* //////////////////////////////////////////////////////////////////// */