// LAPACK++ (V. 1.1)
// (C) 1992-1996 All Rights Reserved.
// Dominik Wagenfuehr <dominik.wagenfuehr@arcor.de>
// Copyright (C) 2006
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 2, or (at
// your option) any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
// You should have received a copy of the GNU Lesser General Public License along
// with this library; see the file COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
/** @file
* @brief Symmetric Positive Definite Band Matrix Class
*/
#ifndef _LA_SYMM_BAND_MAT_DOUBLE_H_
#define _LA_SYMM_BAND_MAT_DOUBLE_H_
#include "arch.h"
#include "lafnames.h"
#include LA_GEN_MAT_DOUBLE_H
/** \brief Symmetric Positive Definite Band Matrix Class
*
* This matrix holds a symmetric positive definite n x n banded
* matrix with bandwidth p, that it, with k subdiagonals and k
* superdiagonals the bandwidth will be \f$ p=2k+1 \f$.
*
* Internally a general matrix with dimension \f$2p+1 \times n\f$
* will be created for storage.
*
* For factorization of this matrix see functions in \ref sybfd.h .
*
* \see http://en.wikipedia.org/wiki/Band_matrix explains a
* general band matrix (not necessarily symmetric).
*/
class DLLIMPORT LaSymmBandMatDouble
{
LaGenMatDouble data_; // internal storage.
int N_; // N_ is (NxN)
int kl_; // kl_ = # subdiags
static double outofbounds_; // out of range value returned.
static int debug_; // print debug info.
static int *info_; // print matrix info only, not values
// originally 0, set to 1, and then
// reset to 0 after use.
public:
/** @name Declaration */
//@{
/*::::::::::::::::::::::::::*/
/* Constructors/Destructors */
/*::::::::::::::::::::::::::*/
/**
* Constructs a null 0x0 matrix.
*/
LaSymmBandMatDouble();
/**
* Constructs a n x n symmetric matrix with bandwidth p, that is,
* with k subdiagonals and k superdiagonals the bandwidth will be
* \f$ p=2k+1 \f$.
*/
LaSymmBandMatDouble(int n, int p);
/**
* Create (deep) copy of another matrix.
*/
LaSymmBandMatDouble(const LaSymmBandMatDouble& A);
/**
* Destroy matrix.
*/
~LaSymmBandMatDouble();
/**
* Resize to a \e new matrix of dimension n x n with bandwidth p.
*/
LaSymmBandMatDouble& resize(int n, int p);
/**
* Resize to a \e new matrix with same dimension and bandwidth as A.
*/
LaSymmBandMatDouble& resize(const LaSymmBandMatDouble& ob);
//@}
/** @name Assignments and Access */
//@{
/**
* Set elements of left-hand side to the scalar value s.
*/
LaSymmBandMatDouble& operator=(double scalar);
/**
* Copy elements of other matrix. This is an alias for copy().
*/
LaSymmBandMatDouble& operator=(const LaSymmBandMatDouble& ob);
/**
* Return element (i,j) of the matrix. Start index is (0,0)
* (zero-based offset).
*
* Optional runtime bounds checking (0 <= i,j < n) is set
* by the compile time macro LA_BOUNDS_CHECK.
*/
double& operator()(int i, int j);
/**
* Return element (i,j) of the matrix. Start index is (0,0)
* (zero-based offset).
*
* Optional runtime bounds checking (0 <= i,j < n) is set
* by the compile time macro LA_BOUNDS_CHECK.
*/
double& operator()(int i, int j) const;
/**
* Let this matrix reference the given matrix \c ob, so that the
* given matrix memory s is now referenced by multiple objects
* (by the given object ob and now also by this object).
*/
inline LaSymmBandMatDouble& ref(LaSymmBandMatDouble &ob);
/**
* Release left-hand side and copy elements of elements
* of \c ob.
*/
LaSymmBandMatDouble& copy(const LaSymmBandMatDouble &ob);
//@}
/** @name Information */
//@{
/**
* Returns the length N of the dth dimension. Because
* the matrix is symmetric it is
* \e size(0) == \e size(1) == \e N.
*
* <b>Important:</b> The size does not return the
* size of the internal stored matrix as it
* was in Lapack versions <= 2.4.13.
*/
inline int size(int d) const; // submatrix size
/**
* Returns the distance between memory locations (in terms of
* number of elements) between consecutive elements along
* dimension d. For example, if \c inc(d) returns 1, then
* elements along the dth dimension are contiguous in
* memory.
*/
inline int inc(int d) const; // explicit increment
/**
* Returns the global dimensions of the (possibly larger)
* matrix owning this space. This will only differ from \c
* size(d) if the current matrix is actually a submatrix view
* of some larger matrix.
*/
inline int gdim(int d) const; // global dimensions
/**
* Returns the memory address of the first element of the
* matrix. \c G.addr() is equivalent to \c &G(0,0) .
*/
inline double* addr() const
{
return data_.addr();
}
/**
* Returns the number of data objects which utilize the same
* (or portions of the same) memory space used by this
* matrix.
*/
inline int ref_count() const
{
return data_.ref_count();
}
/**
* Returns the index specifying this submatrix view in
* dimension \c d. (See \ref LaIndex class.) This will only
* differ from a unit-stride index if the current matrix is
* actually a submatrix view of some larger matrix.
*/
inline LaIndex index(int d) const
{
return data_.index(d);
}
/** Returns bandwidth of matrix.
*
* Watch out: Contrary to the name of this method, it does \e
* not return the number of subdiagonals. Instead the bandwidth
* p is returned, that is, with k subdiagonals and k
* superdiagonals the bandwidth will be \f$ p=2k+1 \f$.
*/
inline int subdiags()
{
return (kl_);
}
/** Returns bandwidth of matrix.
*
* Watch out: Contrary to the name of this method, it does \e
* not return the number of superdiagonals. Instead the
* bandwidth p is returned, that is, with k subdiagonals and k
* superdiagonals the bandwidth will be \f$ p=2k+1 \f$.
*/
inline int subdiags() const
{
return (kl_);
}
//@}
/** @name Debugging information */
//@{
/** Returns global shallow flag */
inline int shallow() const
{
return data_.shallow();
}
/** Returns global debug flag */
inline int debug() const
{
return debug_;
}
/** Set global debug flag */
inline int debug(int d)
{
return debug_ = d;
}
inline const LaSymmBandMatDouble& info() const
{
int *t = info_;
*t = 1;
return *this;
};
/**
* Print the matrix info (not the actual elements)
* to the standard output. */
inline void print_data() const
{
std::cout << data_;
}
//@}
/** Print the matrix to the given output stream. If the matrix
* info flag is set, then this prints only the matrix info,
* see LaGenMatDouble::info(). Otherwise all matrix elements
* are printed.
*
* @see LaPreferences::setPrintFormat()
*/
friend std::ostream& operator<<(std::ostream &s, const LaSymmBandMatDouble &ob);
};
// member functions and operators
inline LaSymmBandMatDouble& LaSymmBandMatDouble::ref(LaSymmBandMatDouble &ob)
{
data_.ref(ob.data_);
N_ = ob.N_;
kl_ = ob.kl_;
return *this;
}
inline int LaSymmBandMatDouble::size(int d) const
{
return(data_.size(1));
}
inline int LaSymmBandMatDouble::inc(int d) const
{
return(data_.inc(d));
}
inline int LaSymmBandMatDouble::gdim(int d) const
{
return(data_.gdim(d));
}
inline double& LaSymmBandMatDouble::operator()(int i, int j)
{
#ifdef LA_BOUNDS_CHECK
assert(i >= 0);
assert(i < N_);
assert(j >= 0);
assert(j < N_);
#endif
if (i >= j)
{
if (i-j <= kl_)
return data_(kl_ + i - j, j);
else
{
#ifdef LA_BOUNDS_CHECK
assert(0);
#else
return outofbounds_;
#endif
}
}
else // if (j>i)
{
if (j-i <= kl_)
return data_(kl_ + j - i,i);
else
{
#ifdef LA_BOUNDS_CHECK
assert(0);
#else
return outofbounds_;
#endif
}
}
}
inline double& LaSymmBandMatDouble::operator()(int i, int j) const
{
#ifdef LA_BOUNDS_CHECK
assert(i >= 0);
assert(i < N_);
assert(j >= 0);
assert(j < N_);
#endif
if (i >= j)
{
if (i-j <= kl_)
return data_(kl_ + i - j, j);
else
{
#ifdef LA_BOUNDS_CHECK
assert(0);
#else
return outofbounds_;
#endif
}
}
else // if (j>i)
{
if (j-i <= kl_)
return data_(kl_ + j - i,i);
else
{
#ifdef LA_BOUNDS_CHECK
assert(0);
#else
return outofbounds_;
#endif
}
}
}
#endif
// _LA_SYMM_BAND_MAT_DOUBLE_H_
syntax highlighted by Code2HTML, v. 0.9.1