26#if ! defined (octave_Sparse_h)
27#define octave_Sparse_h 1
29#include "octave-config.h"
44template <
typename T,
typename Alloc>
74 octave::refcount<octave_idx_type>
m_count;
77 :
Alloc (), m_data (T_allocate (1)), m_ridx (idx_type_allocate (1)),
78 m_cidx (idx_type_allocate (1)),
79 m_nzmax (1), m_nrows (0), m_ncols (0), m_count (1)
83 :
Alloc (), m_data (T_allocate (1)), m_ridx (idx_type_allocate (1)),
84 m_cidx (idx_type_allocate (n+1)),
85 m_nzmax (1), m_nrows (n), m_ncols (n), m_count (1)
89 :
Alloc (), m_data (T_allocate (nz > 0 ? nz : 1)),
90 m_ridx (idx_type_allocate (nz > 0 ? nz : 1)),
91 m_cidx (idx_type_allocate (nc+1)),
92 m_nzmax (nz > 0 ? nz : 1), m_nrows (nr), m_ncols (nc), m_count (1)
97 :
Alloc (), m_data (T_allocate (nz)),
98 m_ridx (idx_type_allocate (nz)),
99 m_cidx (idx_type_allocate (nc+1)),
100 m_nzmax (nz), m_nrows (nr), m_ncols (nc), m_count (1)
102 std::copy_n (
d, nz, m_data);
103 std::copy_n (r, nz, m_ridx);
104 std::copy_n (c, m_ncols + 1, m_cidx);
107 template <
typename U>
110 :
Alloc (), m_data (T_allocate (nz)),
111 m_ridx (idx_type_allocate (nz)),
112 m_cidx (idx_type_allocate (nc+1)),
113 m_nzmax (nz), m_nrows (nr), m_ncols (nc), m_count (1)
115 std::copy_n (
d, nz, m_data);
116 std::copy_n (r, nz, m_ridx);
117 std::copy_n (c, nc + 1, m_cidx);
120 template <
typename U>
124 :
Alloc (xallocator), m_data (
d), m_ridx (r), m_cidx (c),
125 m_nzmax (nz), m_nrows (dv(0)), m_ncols (dv(1)), m_count (1)
129 :
Alloc (), m_data (T_allocate (a.m_nzmax)),
130 m_ridx (idx_type_allocate (a.m_nzmax)),
131 m_cidx (idx_type_allocate (a.m_ncols + 1)),
132 m_nzmax (a.m_nzmax), m_nrows (a.m_nrows), m_ncols (a.m_ncols),
136 std::copy_n (a.
m_data, nz, m_data);
137 std::copy_n (a.
m_ridx, nz, m_ridx);
138 std::copy_n (a.
m_cidx, m_ncols + 1, m_cidx);
143 T_deallocate (m_data, m_nzmax);
144 idx_type_deallocate (m_ridx, m_nzmax);
145 idx_type_deallocate (m_cidx, m_ncols + 1);
171 OCTAVE_API void maybe_compress (
bool remove_zeros);
179 OCTAVE_API bool any_element_is_inf_or_nan ()
const;
184 template <
typename U,
typename A>
friend class Sparse;
192 typename T_Alloc_traits::allocator_type& alloc = *
this;
195 for (
size_t i = 0; i <
len; i++)
196 T_Alloc_traits::construct (alloc, data+i);
203 typename T_Alloc_traits::allocator_type& alloc = *
this;
205 for (
size_t i = 0; i <
len; i++)
206 T_Alloc_traits::destroy (alloc, data+i);
207 T_Alloc_traits::deallocate (alloc, data,
len);
212 typename idx_type_Alloc_traits::allocator_type alloc = *
this;
215 for (
size_t i = 0; i <
len; i++)
216 idx_type_Alloc_traits::construct (alloc, idx+i);
223 typename idx_type_Alloc_traits::allocator_type alloc = *
this;
225 for (
size_t i = 0; i <
len; i++)
226 idx_type_Alloc_traits::destroy (alloc, idx+i);
227 idx_type_Alloc_traits::deallocate (alloc, idx,
len);
235 if (m_rep->m_count > 1)
239 if (--m_rep->m_count == 0)
259 : m_rep (nil_rep ()), m_dimensions (
dim_vector (0, 0))
276 m_dimensions (dv) { }
301 template <
typename U>
304 a.nzmax (), a.data (),
305 a.ridx (), a.cidx ())),
306 m_dimensions (a.dims ()) { }
310 : m_rep (a.m_rep), m_dimensions (a.m_dimensions)
322 Sparse (
const Array<T>& a,
const octave::idx_vector& r,
const octave::idx_vector& c,
358 while (cidx (ret+1) < k)
365 return (
static_cast<std::size_t
> (cols () + 1) *
sizeof (
octave_idx_type)
366 +
static_cast<std::size_t
> (nzmax ())
411 return m_rep->
celem (i, j);
425 if (n < 0 || n >=
numel ())
426 range_error (
"T& Sparse<T>::checkelem", n);
436 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
437 range_error (
"T& Sparse<T>::checkelem", i, j);
450 range_error (
"T& Sparse<T>::checkelem",
ra_idx);
487 if (n < 0 || n >=
numel ())
488 range_error (
"T Sparse<T>::checkelem", n);
495 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ())
496 range_error (
"T Sparse<T>::checkelem", i, j);
506 range_error (
"T Sparse<T>::checkelem",
ra_idx);
546 return permute (vec,
true);
567 bool issquare ()
const {
return (dim1 () == dim2 ()); }
569 bool isempty ()
const {
return (rows () < 1 || cols () < 1); }
585 make_unique ();
return m_rep->
ridx (i);
598 make_unique ();
return m_rep->
cidx (i);
610 OCTAVE_API void delete_elements (
const octave::idx_vector& i);
612 OCTAVE_API void delete_elements (
int dim,
const octave::idx_vector& i);
614 OCTAVE_API void delete_elements (
const octave::idx_vector& i,
const octave::idx_vector& j);
617 index (
const octave::idx_vector& i,
bool resize_ok =
false)
const;
620 index (
const octave::idx_vector& i,
const octave::idx_vector& j,
621 bool resize_ok =
false)
const;
623 OCTAVE_API void assign (
const octave::idx_vector& i,
626 OCTAVE_API void assign (
const octave::idx_vector& i,
const T& rhs);
629 assign (
const octave::idx_vector& i,
const octave::idx_vector& j,
633 assign (
const octave::idx_vector& i,
const octave::idx_vector& j,
637 print_info (std::ostream& os,
const std::string& prefix)
const;
654 template <
typename F,
bool zero>
657 return octave::any_all_test<F, T, zero> (fcn, data (), nnz ());
661 template <
typename F>
663 {
return test<F, false> (fcn); }
665 template <
typename F>
667 {
return test<F, true> (fcn); }
671 {
return test<bool (&) (T), false> (fcn); }
674 {
return test<bool (&) (const T&), false> (fcn); }
677 {
return test<bool (&) (T), true> (fcn); }
680 {
return test<bool (&) (const T&), true> (fcn); }
682 template <
typename U,
typename F>
687 U f_zero = fcn (0.0);
701 result.
data (ridx (i) + j * nr) = fcn (data (i));
714 result.
cidx (ii) = 0;
720 U val = fcn (data (i));
723 result.
data (ii) = val;
724 result.
ridx (ii++) = ridx (i);
728 result.
cidx (j+1) = ii;
738 template <
typename U>
741 {
return map<U, U (&) (T)> (fcn); }
743 template <
typename U>
745 map (U (&fcn) (
const T&))
const
746 {
return map<U, U (&) (const T&)> (fcn); }
761 T (*read_fcn) (std::istream&));
octave_idx_type compute_index(octave_idx_type n, const dim_vector &dims)
std::istream & read_sparse_matrix(std::istream &is, Sparse< T > &a, T(*read_fcn)(std::istream &))
N Dimensional Array with copy-on-write semantics.
SparseRep(const dim_vector &dv, octave_idx_type nz, U *d, octave_idx_type *r, octave_idx_type *c, const Alloc &xallocator=Alloc())
octave_idx_type cols() const
bool any_element_is_nan() const
void change_length(octave_idx_type nz)
octave_idx_type nzmax() const
octave_idx_type nnz() const
void T_deallocate(T_pointer data, size_t len)
octave::refcount< octave_idx_type > m_count
Alloc_traits::template rebind_traits< T > T_Alloc_traits
SparseRep(octave_idx_type n)
SparseRep(octave_idx_type nr, octave_idx_type nc, octave_idx_type nz, const T *d, const octave_idx_type *r, const octave_idx_type *c)
octave_idx_type columns() const
octave_idx_type rows() const
T cdata(octave_idx_type i) const
T_pointer T_allocate(size_t len)
SparseRep(const SparseRep &a)
T & data(octave_idx_type i)
void maybe_compress(bool remove_zeros)
octave_idx_type & ridx(octave_idx_type i)
SparseRep(octave_idx_type nr, octave_idx_type nc, octave_idx_type nz=1)
octave_idx_type length() const
SparseRep(octave_idx_type nr, octave_idx_type nc, octave_idx_type nz, const U *d, const octave_idx_type *r, const octave_idx_type *c)
T & elem(octave_idx_type r, octave_idx_type c)
T_Alloc_traits::pointer T_pointer
idx_type_pointer idx_type_allocate(size_t len)
std::allocator_traits< Alloc > Alloc_traits
octave_idx_type cridx(octave_idx_type i) const
idx_type_Alloc_traits::pointer idx_type_pointer
octave_idx_type & cidx(octave_idx_type i)
octave_idx_type ccidx(octave_idx_type i) const
Alloc_traits::template rebind_traits< octave_idx_type > idx_type_Alloc_traits
T celem(octave_idx_type r, octave_idx_type c) const
bool any_element_is_inf_or_nan() const
void idx_type_deallocate(idx_type_pointer idx, size_t len)
T & data(octave_idx_type i)
octave_idx_type cols() const
Sparse< U > map(U(&fcn)(const T &)) const
T xelem(const Array< octave_idx_type > &ra_idx) const
Sparse(octave_idx_type nr, octave_idx_type nc, octave_idx_type nz)
bool test_all(F fcn) const
octave_idx_type * ridx() const
octave_idx_type nzmax() const
Amount of storage for nonzero elements.
T checkelem(octave_idx_type n) const
Sparse(const dim_vector &dv, octave_idx_type nz)
T elem(const Array< octave_idx_type > &ra_idx) const
octave_idx_type get_col_index(octave_idx_type k)
octave_idx_type & ridx(octave_idx_type i)
octave_idx_type columns() const
bool test_any(bool(&fcn)(const T &)) const
T xelem(octave_idx_type n) const
T & xelem(octave_idx_type i, octave_idx_type j)
T & elem(octave_idx_type i, octave_idx_type j)
bool test_any(bool(&fcn)(T)) const
Sparse< T, Alloc > squeeze() const
T & checkelem(octave_idx_type n)
Sparse(octave_idx_type n)
octave_idx_type * cidx() const
octave_idx_type get_row_index(octave_idx_type k)
Sparse< U > map(F fcn) const
bool test_any(F fcn) const
T checkelem(const Array< octave_idx_type > &ra_idx) const
T & elem(octave_idx_type n)
octave_idx_type ridx(octave_idx_type i) const
octave_idx_type & xridx(octave_idx_type i)
octave_idx_type ndims() const
T elem(octave_idx_type n) const
T & checkelem(const Array< octave_idx_type > &ra_idx)
bool test_all(bool(&fcn)(T)) const
Sparse(const Sparse< U > &a)
octave_idx_type numel() const
T & elem(const Array< octave_idx_type > &ra_idx)
Sparse< T, Alloc > ipermute(const Array< octave_idx_type > &vec) const
bool any_element_is_inf_or_nan() const
T data(octave_idx_type i) const
bool test_all(bool(&fcn)(const T &)) const
Sparse(const dim_vector &dv, octave_idx_type nz, T *ptr, octave_idx_type *ridx, octave_idx_type *cidx, const Alloc &xallocator=Alloc())
T & xdata(octave_idx_type i)
T xelem(octave_idx_type i, octave_idx_type j) const
Sparse< T, Alloc > maybe_compress(bool remove_zeros=false)
std::size_t byte_size() const
octave_idx_type dim2() const
octave_idx_type dim1() const
T elem(octave_idx_type i, octave_idx_type j) const
octave_idx_type nnz() const
Actual number of nonzero terms.
Sparse(const Sparse< T, Alloc > &a)
T checkelem(octave_idx_type i, octave_idx_type j) const
octave_idx_type rows() const
T & xelem(const Array< octave_idx_type > &ra_idx)
void change_capacity(octave_idx_type nz)
Sparse(octave_idx_type nr, octave_idx_type nc)
T & checkelem(octave_idx_type i, octave_idx_type j)
Sparse< U > map(U(&fcn)(T)) const
T & xelem(octave_idx_type n)
octave_idx_type cidx(octave_idx_type i) const
Sparse< T, Alloc >::SparseRep * m_rep
bool any_element_is_nan() const
octave_idx_type & cidx(octave_idx_type i)
octave_idx_type & xcidx(octave_idx_type i)
octave_idx_type * xcidx()
octave_idx_type * xridx()
Vector representing the dimensions (size) of an Array.
octave_idx_type safe_numel() const
The following function will throw a std::bad_alloc () exception if the requested size is larger than ...
octave_idx_type ndims() const
Number of dimensions.
T::size_type numel(const T &str)
const octave_base_value const Array< octave_idx_type > & ra_idx
F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE * d