we need an autodiff library at some point (or we need to roll our own but I do not think that makes sense). CppAD is well tested and header only and easy to include. It is also Liscene compatible with GPL v3.0. Here we bring it in as a dependency
316 lines
8.5 KiB
C++
316 lines
8.5 KiB
C++
# ifndef CPPAD_UTILITY_SPARSE_RCV_HPP
|
|
# define CPPAD_UTILITY_SPARSE_RCV_HPP
|
|
/* --------------------------------------------------------------------------
|
|
CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell
|
|
|
|
CppAD is distributed under the terms of the
|
|
Eclipse Public License Version 2.0.
|
|
|
|
This Source Code may also be made available under the following
|
|
Secondary License when the conditions for such availability set forth
|
|
in the Eclipse Public License, Version 2.0 are satisfied:
|
|
GNU General Public License, Version 2.0 or later.
|
|
---------------------------------------------------------------------------- */
|
|
|
|
/*
|
|
------------------------------------------------------------------------------
|
|
$begin sparse_rcv$$
|
|
$spell
|
|
CppAD
|
|
nr
|
|
nc
|
|
const
|
|
var
|
|
nnz
|
|
cppad
|
|
hpp
|
|
rcv
|
|
rc
|
|
Eigen
|
|
$$
|
|
$section Sparse Matrix Row, Column, Value Representation$$
|
|
|
|
$head Syntax$$
|
|
$codei%# include <cppad/utility/sparse_rcv.hpp>
|
|
%$$
|
|
$codei%sparse_rcv<%SizeVector%, %ValueVector%> %empty%
|
|
%$$
|
|
$codei%sparse_rcv<%SizeVector%, %ValueVector%> %matrix%(%pattern%)
|
|
%$$
|
|
$icode%matrix% = %other%
|
|
%$$
|
|
$icode%matrix%.swap( %other% )
|
|
%$$
|
|
$icode%matrix%.set(%k%, %v%)
|
|
%$$
|
|
$icode%nr% = %matrix%.nr()
|
|
%$$
|
|
$icode%nc% = %matrix%.nc()
|
|
%$$
|
|
$icode%nnz% = %matrix%.nnz()
|
|
%$$
|
|
$codei%const %SizeVector%& %row%( %matrix%.row() )
|
|
%$$
|
|
$codei%const %SizeVector%& %col%( %matrix%.col() )
|
|
%$$
|
|
$codei%const %ValueVector%& %val%( %matrix%.val() )
|
|
%$$
|
|
$codei%const sparse_rc<%SizeVector%>& %pat%( %matrix%.pat() )
|
|
%$$
|
|
$icode%row_major% = %matrix%.row_major()
|
|
%$$
|
|
$icode%col_major% = %matrix%.col_major()
|
|
%$$
|
|
|
|
$head SizeVector$$
|
|
We use $cref/SizeVector/sparse_rc/SizeVector/$$ to denote the
|
|
$cref SimpleVector$$ class corresponding to $icode pattern$$.
|
|
|
|
$head ValueVector$$
|
|
We use $icode ValueVector$$ to denote the
|
|
$cref SimpleVector$$ class corresponding to $icode val$$.
|
|
|
|
$head empty$$
|
|
This is an empty sparse matrix object. To be specific,
|
|
the corresponding number of rows $icode nr$$,
|
|
number of columns $icode nc$$,
|
|
and number of possibly non-zero values $icode nnz$$,
|
|
are all zero.
|
|
|
|
|
|
$head pattern$$
|
|
This constructor argument has prototype
|
|
$codei%
|
|
const sparse_rc<%SizeVector%>& %pattern%
|
|
%$$
|
|
It specifies the number of rows, number of columns and
|
|
the possibly non-zero entries in the $icode matrix$$.
|
|
|
|
$head matrix$$
|
|
This is a sparse matrix object with the sparsity specified by $icode pattern$$.
|
|
Only the $icode val$$ vector can be changed. All other values returned by
|
|
$icode matrix$$ are fixed during the constructor and constant there after.
|
|
The $icode val$$ vector is only changed by the constructor
|
|
and the $code set$$ function.
|
|
There are two exceptions to this rule, where $icode other$$ appears in the
|
|
assignment and swap syntax.
|
|
|
|
$head other$$
|
|
The $icode other$$ variable has prototype
|
|
$codei%
|
|
sparse_rcv<%SizeVector%, %ValueVector%> %other%
|
|
%$$
|
|
|
|
$subhead Assignment$$
|
|
After this assignment statement, $icode other$$ is an independent copy
|
|
of $icode matrix$$; i.e. it has all the same values as $icode matrix$$
|
|
and changes to $icode other$$ do not affect $icode matrix$$.
|
|
A move semantics version of the assignment operator is defined; e.g.,
|
|
it is used when $icode other$$ in the assignment syntax
|
|
is a function return value;
|
|
|
|
$subhead swap$$
|
|
After the swap operation $icode other$$ ($icode matrix$$) is equivalent
|
|
to $icode matrix$$ ($icode other$$) before the operation.
|
|
|
|
$head nr$$
|
|
This return value has prototype
|
|
$codei%
|
|
size_t %nr%
|
|
%$$
|
|
and is the number of rows in $icode matrix$$.
|
|
|
|
$head nc$$
|
|
This argument and return value has prototype
|
|
$codei%
|
|
size_t %nc%
|
|
%$$
|
|
and is the number of columns in $icode matrix$$.
|
|
|
|
$head nnz$$
|
|
We use the notation $icode nnz$$ to denote the number of
|
|
possibly non-zero entries in $icode matrix$$.
|
|
|
|
$head set$$
|
|
This function sets the value
|
|
$codei%
|
|
%val%[%k%] = %v%
|
|
%$$
|
|
|
|
$subhead k$$
|
|
This argument has type
|
|
$codei%
|
|
size_t %k%
|
|
%$$
|
|
and must be less than $icode nnz$$.
|
|
|
|
$subhead v$$
|
|
This argument has type
|
|
$codei%
|
|
const %ValueVector%::value_type& %v%
|
|
%$$
|
|
It specifies the value assigned to $icode%val%[%k%]%$$.
|
|
|
|
|
|
$head row$$
|
|
This vector has size $icode nnz$$ and
|
|
$icode%row%[%k%]%$$
|
|
is the row index of the $th k$$ possibly non-zero
|
|
element in $icode matrix$$.
|
|
|
|
$head col$$
|
|
This vector has size $icode nnz$$ and
|
|
$icode%col[%k%]%$$ is the column index of the $th k$$ possibly non-zero
|
|
element in $icode matrix$$
|
|
|
|
$head val$$
|
|
This vector has size $icode nnz$$ and
|
|
$icode%val[%k%]%$$ is value of the $th k$$ possibly non-zero entry
|
|
in the sparse matrix (the value may be zero).
|
|
|
|
$head pat$$
|
|
This is equal to the sparsity pattern; i.e.,
|
|
$icode pattern$$ in the constructor.
|
|
|
|
$head row_major$$
|
|
This vector has prototype
|
|
$codei%
|
|
%SizeVector% %row_major%
|
|
%$$
|
|
and its size $icode nnz$$.
|
|
It sorts the sparsity pattern in row-major order.
|
|
To be specific,
|
|
$codei%
|
|
%col%[ %row_major%[%k%] ] <= %col%[ %row_major%[%k%+1] ]
|
|
%$$
|
|
and if $icode%col%[ %row_major%[%k%] ] == %col%[ %row_major%[%k%+1] ]%$$,
|
|
$codei%
|
|
%row%[ %row_major%[%k%] ] < %row%[ %row_major%[%k%+1] ]
|
|
%$$
|
|
This routine generates an assert if there are two entries with the same
|
|
row and column values (if $code NDEBUG$$ is not defined).
|
|
|
|
$head col_major$$
|
|
This vector has prototype
|
|
$codei%
|
|
%SizeVector% %col_major%
|
|
%$$
|
|
and its size $icode nnz$$.
|
|
It sorts the sparsity pattern in column-major order.
|
|
To be specific,
|
|
$codei%
|
|
%row%[ %col_major%[%k%] ] <= %row%[ %col_major%[%k%+1] ]
|
|
%$$
|
|
and if $icode%row%[ %col_major%[%k%] ] == %row%[ %col_major%[%k%+1] ]%$$,
|
|
$codei%
|
|
%col%[ %col_major%[%k%] ] < %col%[ %col_major%[%k%+1] ]
|
|
%$$
|
|
This routine generates an assert if there are two entries with the same
|
|
row and column values (if $code NDEBUG$$ is not defined).
|
|
|
|
$head Eigen Matrix$$
|
|
If you have the $cref/eigen package/eigen/$$ in your include path,
|
|
you can use $cref sparse2eigen$$ to convert a sparse matrix to eigen format.
|
|
|
|
$children%
|
|
example/utility/sparse_rcv.cpp
|
|
%$$
|
|
$head Example$$
|
|
The file $cref sparse_rcv.cpp$$
|
|
contains an example and test of this class.
|
|
|
|
$end
|
|
*/
|
|
/*!
|
|
\file sparse_rcv.hpp
|
|
A sparse matrix class.
|
|
*/
|
|
# include <cppad/utility/sparse_rc.hpp>
|
|
|
|
namespace CppAD { // BEGIN CPPAD_NAMESPACE
|
|
|
|
/// Sparse matrices with elements of type Scalar
|
|
template <class SizeVector, class ValueVector>
|
|
class sparse_rcv {
|
|
private:
|
|
/// sparsity pattern
|
|
sparse_rc<SizeVector> pattern_;
|
|
/// value_type
|
|
typedef typename ValueVector::value_type value_type;
|
|
/// val_[k] is the value for the k-th possibly non-zero entry in the matrix
|
|
ValueVector val_;
|
|
public:
|
|
// ------------------------------------------------------------------------
|
|
/// default constructor
|
|
sparse_rcv(void)
|
|
: pattern_(0, 0, 0)
|
|
{ }
|
|
/// move semantics constructor
|
|
/// (none of the default constructor values are used by destructor)
|
|
sparse_rcv(sparse_rcv&& other)
|
|
{ swap(other); }
|
|
/// destructor
|
|
~sparse_rcv(void)
|
|
{ }
|
|
/// constructor
|
|
sparse_rcv(const sparse_rc<SizeVector>& pattern )
|
|
:
|
|
pattern_(pattern) ,
|
|
val_(pattern_.nnz())
|
|
{ }
|
|
/// assignment
|
|
void operator=(const sparse_rcv& other)
|
|
{ pattern_ = other.pattern_;
|
|
// simple vector assignment requires vectors to have same size
|
|
val_.resize( other.nnz() );
|
|
val_ = other.val();
|
|
}
|
|
/// swap
|
|
void swap(sparse_rcv& other)
|
|
{ pattern_.swap( other.pattern_ );
|
|
val_.swap( other.val_ );
|
|
}
|
|
/// move semantics assignment
|
|
void operator=(sparse_rcv&& other)
|
|
{ swap(other); }
|
|
// ------------------------------------------------------------------------
|
|
void set(size_t k, const value_type& v)
|
|
{ CPPAD_ASSERT_KNOWN(
|
|
pattern_.nnz(),
|
|
"The index k is not less than nnz in sparse_rcv::set"
|
|
);
|
|
val_[k] = v;
|
|
}
|
|
/// number of rows in matrix
|
|
size_t nr(void) const
|
|
{ return pattern_.nr(); }
|
|
/// number of columns in matrix
|
|
size_t nc(void) const
|
|
{ return pattern_.nc(); }
|
|
/// number of possibly non-zero elements in matrix
|
|
size_t nnz(void) const
|
|
{ return pattern_.nnz(); }
|
|
/// row indices
|
|
const SizeVector& row(void) const
|
|
{ return pattern_.row(); }
|
|
/// column indices
|
|
const SizeVector& col(void) const
|
|
{ return pattern_.col(); }
|
|
/// value for possibly non-zero elements
|
|
const ValueVector& val(void) const
|
|
{ return val_; }
|
|
/// sparsity pattern
|
|
const sparse_rc<SizeVector>& pat(void) const
|
|
{ return pattern_; }
|
|
/// row-major order
|
|
SizeVector row_major(void) const
|
|
{ return pattern_.row_major(); }
|
|
/// column-major indices
|
|
SizeVector col_major(void) const
|
|
{ return pattern_.col_major(); }
|
|
};
|
|
|
|
} // END_CPPAD_NAMESPACE
|
|
|
|
# endif
|