1 /* ///////////////////////////////////////////////////////////////////////
2 * File: symmetrical_matrix.h
7 * Brief: symmetrical_matrix class - compact matrix
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 /* ///////////////////////////////////////////////////////////////////////
24 #include "../memory/buffer.h"
25 #include "matrix_base.h"
27 /* ///////////////////////////////////////////////////////////////////////
33 /*!\brief: symmetrical_matrix class - compact matrix
36 * using upper triangular matrix
37 * size = n * (n + 1) / 2
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
57 , typename_param_k Buf
60 class symmetrical_matrix
61 : public matrix_base
< symmetrical_matrix
<Val
, Buf
>
66 typedef matrix_base
< symmetrical_matrix
<Val
, Buf
>
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
98 const_reduced_dimension_type(const_pointer p
, index_type i
, size_type dim
)
104 const_reference
operator[](index_type j
) const
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
125 reduced_dimension_type(pointer p
, index_type i
, size_type dim
)
131 reference
operator[](index_type 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
];
146 /// \name Constructors
153 symmetrical_matrix(class_type
const& rhs
)
157 explicit_k
symmetrical_matrix(index_type d0
, index_type
/*d1*/ = 0)
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);
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(); }
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;
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
); }
209 /* /////////////////////////////////////////////////////////////////////////
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
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
));
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
);
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());
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 /* ///////////////////////////////////////////////////////////////////////
305 /* //////////////////////////////////////////////////////////////////// */
306 #endif /* EXTL_CONTAINER_SYMMETRICAL_MATRIX_H */
307 /* //////////////////////////////////////////////////////////////////// */