1 /* ///////////////////////////////////////////////////////////////////////
2 * File: symmetrical_sparse_matrix.h
7 * Brief: symmetrical_sparse_matrix class - compact matrix
10 * Copyright (c) 2008-2020, Waruqi All rights reserved.
11 * //////////////////////////////////////////////////////////////////// */
13 #ifndef EXTL_CONTAINER_SYMMETRICAL_SPARSE_MATRIX_H
14 #define EXTL_CONTAINER_SYMMETRICAL_SPARSE_MATRIX_H
16 /*!\file symmetrical_sparse_matrix.h
17 * \brief symmetrical_sparse_matrix class
20 /* ///////////////////////////////////////////////////////////////////////
24 #include "sparse_matrix_base.h"
25 #include "detail/symmetrical_sparse_matrix_rowcole_iterator.h"
26 /* ///////////////////////////////////////////////////////////////////////
32 /*!\brief: symmetrical_sparse_matrix class - compact matrix
35 * using upper triangular matrix
36 * size = n * (n + 1) / 2
47 * \param Val The element type
49 * \ingroup extl_group_container
51 template<typename_param_k Val
>
52 class symmetrical_sparse_matrix
53 : public sparse_matrix_base
< symmetrical_sparse_matrix
<Val
>
58 typedef sparse_matrix_base
< symmetrical_sparse_matrix
<Val
>
65 typedef symmetrical_sparse_matrix class_type
;
66 typedef typename_type_k
base_type::allocator_type allocator_type
;
67 typedef typename_type_k
base_type::value_type value_type
;
68 typedef typename_type_k
base_type::pointer pointer
;
69 typedef typename_type_k
base_type::const_pointer const_pointer
;
70 typedef typename_type_k
base_type::reference reference
;
71 typedef typename_type_k
base_type::const_reference const_reference
;
72 typedef typename_type_k
base_type::iterator iterator
;
73 typedef typename_type_k
base_type::const_iterator const_iterator
;
74 typedef typename_type_k
base_type::reverse_iterator reverse_iterator
;
75 typedef typename_type_k
base_type::const_reverse_iterator const_reverse_iterator
;
76 typedef typename_type_k
base_type::size_type size_type
;
77 typedef typename_type_k
base_type::bool_type bool_type
;
78 typedef typename_type_k
base_type::difference_type difference_type
;
79 typedef typename_type_k
base_type::int_type int_type
;
80 typedef typename_type_k
base_type::index_type index_type
;
81 class const_reduced_dimension_type
84 class_type
const* m_this
;
89 const_reduced_dimension_type(class_type
const* p
, index_type i
)
94 const_reference
operator[](index_type j
) const
96 return at_unchecked(j
);
98 const_reference
at(index_type j
) const
100 return m_this
->at(m_i
, j
);
102 const_reference
at_unchecked(index_type j
) const
104 return m_this
->at_unchecked(m_i
, j
);
107 class reduced_dimension_type
110 class_type
const* m_this
;
115 reduced_dimension_type(class_type
const* p
, index_type i
)
120 reference
operator[](index_type j
)
122 return at_unchecked(j
);
124 reference
at(index_type j
)
126 return const_cast<reference
>(m_this
->at(m_i
, j
));
128 reference
at_unchecked(index_type j
)
130 return const_cast<reference
>(m_this
->at_unchecked(m_i
, j
));
135 /// \name Protected Types
138 typedef typename_type_k
base_type::rheads_type rheads_type
;
139 typedef typename_type_k
base_type::cheads_type cheads_type
;
140 typedef typename_type_k
base_type::node_type node_type
;
143 /// \name Iterator Types
146 // row element iterator
147 typedef EXTL_NS_DETAIL(symmetrical_sparse_matrix_rowcole_iterator
)<value_type
, node_type
> rowe_iterator
;
148 typedef EXTL_NS_DETAIL(const_symmetrical_sparse_matrix_rowcole_iterator
)<value_type
, node_type
> const_rowe_iterator
;
149 typedef reverse_bidirectional_iterator_base
<const_rowe_iterator
> rowe_reverse_iterator
;
150 typedef const_reverse_bidirectional_iterator_base
<const_rowe_iterator
> const_rowe_reverse_iterator
;
153 // column element iterator
154 typedef EXTL_NS_DETAIL(symmetrical_sparse_matrix_rowcole_iterator
)<value_type
, node_type
> cole_iterator
;
155 typedef EXTL_NS_DETAIL(const_symmetrical_sparse_matrix_rowcole_iterator
)<value_type
, node_type
> const_cole_iterator
;
156 typedef reverse_bidirectional_iterator_base
<const_cole_iterator
> cole_reverse_iterator
;
157 typedef const_reverse_bidirectional_iterator_base
<const_cole_iterator
> const_cole_reverse_iterator
;
161 /// \name Constructors
164 symmetrical_sparse_matrix()
168 symmetrical_sparse_matrix(class_type
const& rhs
)
172 explicit_k
symmetrical_sparse_matrix(index_type d0
, index_type
/*d1*/ = 0)
181 size_type
dim() const { return this->dim1(); }
182 bool_type
exists(index_type i0
, index_type i1
) const;
185 /// \name Row Element Iterators
188 const_rowe_iterator
rowe_begin(index_type i0
) const { return const_rowe_iterator(this->cheads()[i0
].bottom(), &(this->rheads()[i0
]), &(this->cheads()[i0
])); }
189 rowe_iterator
rowe_begin(index_type i0
) { return rowe_iterator(this->cheads()[i0
].bottom(), &(this->rheads()[i0
]), &(this->cheads()[i0
])); }
191 const_rowe_iterator
rowe_end(index_type i0
) const { return const_rowe_iterator(&(this->rheads()[i0
]), &(this->rheads()[i0
]), &(this->cheads()[i0
])); }
192 rowe_iterator
rowe_end(index_type i0
) { return rowe_iterator(&(this->rheads()[i0
]), &(this->rheads()[i0
]), &(this->cheads()[i0
])); }
194 const_rowe_reverse_iterator
rowe_rbegin(index_type i0
) const { return const_rowe_reverse_iterator(rowe_end(i0
)); }
195 rowe_reverse_iterator
rowe_rbegin(index_type i0
) { return rowe_reverse_iterator(rowe_end(i0
)); }
197 const_rowe_reverse_iterator
rowe_rend(index_type i0
) const { return const_rowe_reverse_iterator(rowe_begin(i0
)); }
198 rowe_reverse_iterator
rowe_rend(index_type i0
) { return rowe_reverse_iterator(rowe_begin(i0
)); }
201 /// \name Column Element Iterators
204 const_cole_iterator
cole_begin(index_type i1
) const { return const_cole_iterator(this->cheads()[i1
].bottom(), &(this->rheads()[i1
]), &(this->cheads()[i1
])); }
205 cole_iterator
cole_begin(index_type i1
) { return cole_iterator(this->cheads()[i1
].bottom(), &(this->rheads()[i1
]), &(this->cheads()[i1
])); }
207 const_cole_iterator
cole_end(index_type i1
) const { return const_cole_iterator(&(this->rheads()[i1
]), &(this->rheads()[i1
]), &(this->cheads()[i1
])); }
208 cole_iterator
cole_end(index_type i1
) { return cole_iterator(&(this->rheads()[i1
]), &(this->rheads()[i1
]), &(this->cheads()[i1
])); }
210 const_cole_reverse_iterator
cole_rbegin(index_type i1
) const { return const_cole_reverse_iterator(cole_end(i1
)); }
211 cole_reverse_iterator
cole_rbegin(index_type i1
) { return cole_reverse_iterator(cole_end(i1
)); }
213 const_cole_reverse_iterator
cole_rend(index_type i1
) const { return const_cole_reverse_iterator(cole_begin(i1
)); }
214 cole_reverse_iterator
cole_rend(index_type i1
) { return cole_reverse_iterator(cole_begin(i1
)); }
220 reduced_dimension_type
at(index_type i0
);
221 const_reduced_dimension_type
at(index_type i0
) const;
223 reduced_dimension_type
at_unchecked(index_type i0
);
224 const_reduced_dimension_type
at_unchecked(index_type i0
) const;
226 reduced_dimension_type
operator[](index_type i0
) { return at_unchecked(i0
); }
227 const_reduced_dimension_type
operator[](index_type i0
) const { return at_unchecked(i0
); }
229 reference
at(index_type i0
, index_type i1
);
230 const_reference
at(index_type i0
, index_type i1
) const;
232 reference
at_unchecked(index_type i0
, index_type i1
);
233 const_reference
at_unchecked(index_type i0
, index_type i1
) const;
235 bool_type
get_if_exists(index_type i0
, index_type i1
, reference ret
) const;
236 bool_type
set_if_exists(index_type i0
, index_type i1
, const_reference val
);
242 const_reference
insert(index_type i0
, index_type i1
, const_reference value
, bool_type
* has_existed
= NULL
);
243 void erase(index_type i0
, index_type i1
, bool_type
* has_existed
= NULL
);
249 class_type
& operator=(class_type
const& rhs
) { return base_type::operator=(rhs
); }
255 /* /////////////////////////////////////////////////////////////////////////
258 // at_unchecked(i0, i1)
259 template<typename_param_k Val
>
260 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
261 const_reference symmetrical_sparse_matrix
<Val
>::at_unchecked(index_type i0
, index_type i1
) const
263 EXTL_MESSAGE_ASSERT(i0
< dim() && i1
< dim(), "out of range");
264 return i0
< i1
? static_cast<base_type
const&>(*this).at_unchecked(i0
, i1
)
265 : static_cast<base_type
const&>(*this).at_unchecked(i1
, i0
);
267 template<typename_param_k Val
>
268 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
269 reference symmetrical_sparse_matrix
<Val
>::at_unchecked(index_type i0
, index_type i1
)
271 return const_cast<reference
>(static_cast<class_type
const&>(*this).at_unchecked(i0
, i1
));
275 template<typename_param_k Val
>
276 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
277 reference symmetrical_sparse_matrix
<Val
>::at(index_type i0
, index_type i1
)
279 return const_cast<reference
>(static_cast<class_type
const&>(*this).at(i0
, i1
));
281 template<typename_param_k Val
>
282 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
283 const_reference symmetrical_sparse_matrix
<Val
>::at(index_type i0
, index_type i1
) const
285 EXTL_ASSERT_THROW(i0
< dim() && i1
< dim(), index_error("out of range"));
286 return at_unchecked(i0
, i1
);
290 template<typename_param_k Val
>
291 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
292 reduced_dimension_type symmetrical_sparse_matrix
<Val
>::at_unchecked(index_type i0
)
294 EXTL_MESSAGE_ASSERT(i0
< dim(), "out of range");
295 return reduced_dimension_type(this, i0
);
297 template<typename_param_k Val
>
298 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
299 const_reduced_dimension_type symmetrical_sparse_matrix
<Val
>::at_unchecked(index_type i0
) const
301 EXTL_MESSAGE_ASSERT(i0
< dim(), "out of range");
302 return const_reduced_dimension_type(this, i0
);
306 template<typename_param_k Val
>
307 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
308 reduced_dimension_type symmetrical_sparse_matrix
<Val
>::at(index_type i0
)
310 EXTL_ASSERT_THROW(i0
< dim(), index_error("out of range"));
311 return at_unchecked(i0
);
313 template<typename_param_k Val
>
314 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
315 const_reduced_dimension_type symmetrical_sparse_matrix
<Val
>::at(index_type i0
) const
317 EXTL_ASSERT_THROW(i0
< dim(), index_error("out of range"));
318 return at_unchecked(i0
);
320 template<typename_param_k Val
>
321 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
322 const_reference symmetrical_sparse_matrix
<Val
>::insert(index_type i0
, index_type i1
, const_reference value
, bool_type
* has_existed
)
324 return i0
< i1
? static_cast<base_type
&>(*this).insert(i0
, i1
, value
, has_existed
)
325 : static_cast<base_type
&>(*this).insert(i1
, i0
, value
, has_existed
);
327 template<typename_param_k Val
>
328 void symmetrical_sparse_matrix
<Val
>::erase(index_type i0
, index_type i1
, bool_type
* has_existed
)
331 static_cast<base_type
&>(*this).erase(i0
, i1
, has_existed
);
332 else static_cast<base_type
&>(*this).erase(i1
, i0
, has_existed
);
334 template<typename_param_k Val
>
335 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
336 bool_type symmetrical_sparse_matrix
<Val
>::exists(index_type i0
, index_type i1
) const
338 return i0
< i1
? static_cast<base_type
const&>(*this).exists(i0
, i1
)
339 : static_cast<base_type
const&>(*this).exists(i1
, i0
);
342 template<typename_param_k Val
>
343 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
344 bool_type symmetrical_sparse_matrix
<Val
>::get_if_exists(index_type i0
, index_type i1
, reference ret
) const
346 return i0
< i1
? static_cast<base_type
const&>(*this).get_if_exists(i0
, i1
, ret
)
347 : static_cast<base_type
const&>(*this).get_if_exists(i1
, i0
, ret
);
349 template<typename_param_k Val
>
350 inline typename_type_ret_k symmetrical_sparse_matrix
<Val
>::
351 bool_type symmetrical_sparse_matrix
<Val
>::set_if_exists(index_type i0
, index_type i1
, const_reference val
)
353 return i0
< i1
? static_cast<base_type
&>(*this).set_if_exists(i0
, i1
, val
)
354 : static_cast<base_type
&>(*this).set_if_exists(i1
, i0
, val
);
358 /* ///////////////////////////////////////////////////////////////////////
363 /* //////////////////////////////////////////////////////////////////// */
364 #endif /* EXTL_CONTAINER_SYMMETRICAL_SPARSE_MATRIX_H */
365 /* //////////////////////////////////////////////////////////////////// */