mirror of https://github.com/CGAL/cgal
added Herves Cartesian linear algebra and debugged it
This commit is contained in:
parent
3e2f0184b4
commit
2e2fe30fbd
|
|
@ -8,7 +8,7 @@
|
|||
#include <CGAL/Kernel/function_objects.h>
|
||||
#include <vector>
|
||||
#endif
|
||||
#include <CGAL/Linear_algebra.h>
|
||||
#include <CGAL/Linear_algebraHd.h>
|
||||
#include <CGAL/Kernel_d/PointHd.h>
|
||||
#include <CGAL/Kernel_d/VectorHd.h>
|
||||
#include <CGAL/Kernel_d/DirectionHd.h>
|
||||
|
|
@ -34,7 +34,7 @@ template <class R> class Ray_d;
|
|||
template <class R> class Line_d;
|
||||
template <class R> class Aff_transformation_d;
|
||||
|
||||
template <class pRT, class pLA = Linear_algebra<pRT> >
|
||||
template <class pRT, class pLA = Linear_algebraHd<pRT> >
|
||||
class Homogeneous_d
|
||||
{
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef CGAL_AFF_TRANSFORMATION_D_H
|
||||
#define CGAL_AFF_TRANSFORMATION_D_H
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class pR>
|
||||
class Aff_transformation_d : public pR::Aff_transformation_d_base
|
||||
{ public:
|
||||
typedef typename pR::Aff_transformation_d_base Base;
|
||||
typedef Aff_transformation_d<pR> Self;
|
||||
typedef pR R;
|
||||
typedef typename R::RT RT;
|
||||
typedef typename R::FT FT;
|
||||
typedef typename R::LA LA;
|
||||
|
||||
Aff_transformation_d(int d = 0, bool identity=false)
|
||||
: Base(d,identity) {}
|
||||
Aff_transformation_d(const typename LA::Matrix& M)
|
||||
: Base(M) {}
|
||||
template <typename Forward_iterator>
|
||||
Aff_transformation_d(
|
||||
Forward_iterator start, Forward_iterator end) : Base(start,end) {}
|
||||
Aff_transformation_d(const Vector_d<R>& v) : Base(v) {}
|
||||
Aff_transformation_d(int d, const RT& num, const RT& den)
|
||||
: Base(d,num,den) {}
|
||||
Aff_transformation_d(int d, const RT& sin_num, const RT& cos_num,
|
||||
const RT& den, int e1 = 0, int e2 = 1)
|
||||
: Base(d,sin_num,cos_num,den,e1,e2) {}
|
||||
Aff_transformation_d(int d, const Direction_d<R>& dir,
|
||||
const RT& num, const RT& den,
|
||||
int e1 = 0, int e2 = 1)
|
||||
: Base(d,dir,num,den,e1,e2) {}
|
||||
Aff_transformation_d(const Base& a) : Base(a) {}
|
||||
Aff_transformation_d(const Self& a) : Base(a) {}
|
||||
|
||||
Self operator*(const Self& a)
|
||||
{ return Base::operator*(a); }
|
||||
Self inverse() const { return Base::inverse(); }
|
||||
|
||||
bool operator==(const Self& a) const
|
||||
{ return Base::operator==(a); }
|
||||
bool operator!=(const Self& a) const
|
||||
{ return Base::operator!=(a); }
|
||||
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
#endif //CGAL_AFF_TRANSFORMATION_D_H
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef CGAL_DIRECTION_D_H
|
||||
#define CGAL_DIRECTION_D_H
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class pR>
|
||||
class Direction_d : public pR::Direction_d_base
|
||||
{ public:
|
||||
typedef typename pR::Direction_d_base Base;
|
||||
typedef Direction_d<pR> Self;
|
||||
typedef pR R;
|
||||
typedef typename R::RT RT;
|
||||
typedef typename R::FT FT;
|
||||
typedef typename R::LA LA;
|
||||
|
||||
Direction_d(int d=0) : Base(d) {}
|
||||
Direction_d(int a, int b) : Base(a,b) {}
|
||||
Direction_d(const RT& a, const RT& b) : Base(a,b) {}
|
||||
Direction_d(int a, int b, int c) : Base(a,b,c) {}
|
||||
Direction_d(const RT& a, const RT& b, const RT& c) : Base(a,b,c) {}
|
||||
template <class InputIterator>
|
||||
Direction_d (int d, InputIterator first, InputIterator last)
|
||||
: Base(d, first, last) {}
|
||||
Direction_d(const Direction_d<R> &d) : Base(d) {}
|
||||
Direction_d(const Vector_d<R> &v) : Base(v) {}
|
||||
Direction_d(typename Base::Base_direction, int d, int i) :
|
||||
Base(typename Base::Base_direction(),d,i) {}
|
||||
Direction_d(const Base& p) : Base(p) {}
|
||||
|
||||
Self operator-() const { return Base::operator-(); }
|
||||
Vector_d<R> vector() const { return Base::vector(); }
|
||||
|
||||
bool operator==(const Self& w) const
|
||||
{ return Base::operator==(w); }
|
||||
bool operator!=(const Self& w) const
|
||||
{ return Base::operator!=(w); }
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
#endif //CGAL_DIRECTION_D_H
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef CGAL_HYPERPLANE_D_H
|
||||
#define CGAL_HYPERPLANE_D_H
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class pR>
|
||||
class Hyperplane_d : public pR::Hyperplane_d_base
|
||||
{ public:
|
||||
typedef typename pR::Hyperplane_d_base Base;
|
||||
typedef Hyperplane_d<pR> Self;
|
||||
typedef pR R;
|
||||
typedef typename R::RT RT;
|
||||
typedef typename R::FT FT;
|
||||
typedef typename R::LA LA;
|
||||
|
||||
Hyperplane_d(int d=0) : Base(d) {}
|
||||
Hyperplane_d(int a, int b, int c) : Base(a,b,c) {}
|
||||
Hyperplane_d(const RT& a, const RT& b, const RT& c) :
|
||||
Base(a,b,c) {}
|
||||
Hyperplane_d(int a, int b, int c, int d) : Base(a,b,c,d) {}
|
||||
Hyperplane_d(const RT& a, const RT& b, const RT& c, const RT& d) :
|
||||
Base(a,b,c,d) {}
|
||||
|
||||
Hyperplane_d(const Point_d<R>& p, const Direction_d<R>& dir) :
|
||||
Base(p,dir) {}
|
||||
|
||||
Hyperplane_d(const Hyperplane_d<R> &h) : Base(h) {}
|
||||
Hyperplane_d(const Base& p) : Base(p) {}
|
||||
|
||||
template <class InputIterator>
|
||||
Hyperplane_d(int d, InputIterator first, InputIterator last)
|
||||
: Base (d, first, last) {}
|
||||
|
||||
template <class InputIterator>
|
||||
Hyperplane_d(int d, InputIterator first, InputIterator last,
|
||||
const RT& D)
|
||||
: Base (d, first, last, D) {}
|
||||
|
||||
template <class ForwardIterator>
|
||||
Hyperplane_d(ForwardIterator first, ForwardIterator last,
|
||||
const Point_d<R>& o, Oriented_side side = Oriented_side(0)) :
|
||||
Base(first,last,o,side) {}
|
||||
|
||||
Vector_d<R> orthogonal_vector() const
|
||||
{ return Base::orthogonal_vector(); }
|
||||
Direction_d<R> orthogonal_direction() const
|
||||
{ return Base::orthogonal_direction(); }
|
||||
|
||||
bool operator==(const Self& w) const
|
||||
{ return Base::operator==(w); }
|
||||
bool operator!=(const Self& w) const
|
||||
{ return Base::operator!=(w); }
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
#endif //CGAL_HYPERPLANE_D_H
|
||||
|
|
@ -33,48 +33,46 @@
|
|||
// debugging and templatization: M. Seel
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef LINALG_IMATRIX_H
|
||||
#define LINALG_IMATRIX_H
|
||||
#ifndef CGAL_IMATRIX_H
|
||||
#define CGAL_IMATRIX_H
|
||||
|
||||
#include <math.h>
|
||||
#include <CGAL/Kernel_d/Ivector.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
/*{\Msubst
|
||||
<>#
|
||||
<_RT,_ALLOC>#<RT,LA>
|
||||
<_NT,_ALLOC>#<NT>
|
||||
Ivector#Vector
|
||||
Imatrix#Matrix
|
||||
}*/
|
||||
/*{\Moptions print_title=yes}*/
|
||||
/*{\Moptions outfile=Imatrix.man}*/
|
||||
/*{\Manpage {Matrix}{NT}{Matrices with NT Entries}{M}}*/
|
||||
|
||||
LA_BEGIN_NAMESPACE
|
||||
|
||||
/*{\Moptions
|
||||
outfile=Imatrix.man
|
||||
}*/
|
||||
/*{\Manpage {Imatrix} {RT} {Matrices with RT Entries} {M}}*/
|
||||
|
||||
template <class _RT, class _ALLOC>
|
||||
template <class _NT, class _ALLOC>
|
||||
class Imatrix
|
||||
{
|
||||
/*{\Mdefinition
|
||||
An instance of data type |Imatrix| is a matrix of variables of type
|
||||
|RT|, the so-called ring type. The arithmetic type |RT| is required to
|
||||
behave like integers in the mathematical sense.
|
||||
/*{\Mdefinition An instance of data type |\Mname| is a matrix of
|
||||
variables of number type |NT|. The types |\Mname| and |Ivector|
|
||||
together realize many functions of basic linear algebra. All
|
||||
functions on integer matrices compute the exact result, i.e., there is
|
||||
no rounding error. |\Mname| offers all simple matrix operations. The
|
||||
more sophisticated ones are provided by the class |Linear_algebra|.
|
||||
Preconditions are checked by default and can be switched off by the
|
||||
compile flag [[CGAL_LA_PRECOND_OFF]].}*/
|
||||
|
||||
The types |Imatrix| and |Ivector| together realize many functions of
|
||||
basic linear algebra. All functions on integer matrices compute the
|
||||
exact result, i.e., there is no rounding error. |\Mname| offers all
|
||||
simple matrix operations. The more sophisticated ones are provided by
|
||||
the class |Linear_algebra|. Preconditions are checked by default and
|
||||
can be switched off by the compile flag [[LA_PRECOND_OFF]].}*/ public:
|
||||
public:
|
||||
|
||||
/*{\Mtypes 5.5}*/
|
||||
|
||||
typedef Ivector<_RT,_ALLOC>* vector_pointer;
|
||||
typedef const Ivector<_RT,_ALLOC>* const_vector_pointer;
|
||||
typedef Ivector<_NT,_ALLOC>* vector_pointer;
|
||||
typedef const Ivector<_NT,_ALLOC>* const_vector_pointer;
|
||||
|
||||
typedef _RT RT;
|
||||
typedef _NT NT;
|
||||
/*{\Mtypemember the ring type of the components.}*/
|
||||
|
||||
typedef Ivector<_RT,_ALLOC> Vector;
|
||||
typedef Ivector<_NT,_ALLOC> Vector;
|
||||
/*{\Mtypemember the vector type used.}*/
|
||||
|
||||
typedef vector_pointer iterator;
|
||||
|
|
@ -83,6 +81,10 @@ typedef vector_pointer iterator;
|
|||
typedef const_vector_pointer const_iterator;
|
||||
/*{\Mtypemember the const iterator type for accessing rows.}*/
|
||||
|
||||
typedef NT* Row_iterator;
|
||||
/*{\Xtypemember accessing row entries.}*/
|
||||
typedef const NT& Row_const_iterator;
|
||||
|
||||
class Identity {};
|
||||
/*{\Mtypemember a tag class for identity initialization}*/
|
||||
|
||||
|
|
@ -94,7 +96,7 @@ protected:
|
|||
int d1;
|
||||
int d2;
|
||||
|
||||
RT& elem(int i, int j) const { return v[i]->v[j]; }
|
||||
NT& elem(int i, int j) const { return v[i]->v[j]; }
|
||||
#ifndef _MSC_VER
|
||||
typedef typename _ALLOC::template rebind<vector_pointer>::other
|
||||
allocator_type;
|
||||
|
|
@ -133,9 +135,9 @@ protected:
|
|||
|
||||
#endif
|
||||
|
||||
inline void check_dimensions(const Imatrix<_RT,_ALLOC>& mat) const
|
||||
inline void check_dimensions(const Imatrix<_NT,_ALLOC>& mat) const
|
||||
{
|
||||
LA_PRECOND((d1 == mat.d1 && d2 == mat.d2),
|
||||
CGAL_LA_PRECOND((d1 == mat.d1 && d2 == mat.d2),
|
||||
"Imatrix::check_dimensions: incompatible matrix dimensions.")
|
||||
}
|
||||
|
||||
|
|
@ -153,11 +155,12 @@ dimension $n \times n$ initialized to the zero matrix.}*/
|
|||
Imatrix(int n, int m);
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname| of
|
||||
dimension $n \times m$ initialized to the zero matrix.}*/
|
||||
Imatrix(int n , const Identity&, const RT& x = RT(1) );
|
||||
Imatrix(std::pair<int,int> p);
|
||||
Imatrix(int n , const Identity&, const NT& x = NT(1) );
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname| of
|
||||
dimension $n \times n$ initialized to the identity matrix
|
||||
(times |x|).}*/
|
||||
Imatrix(int n, int m, const Initialize&, const RT& x);
|
||||
Imatrix(int n, int m, const Initialize&, const NT& x);
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname| of
|
||||
dimension $n \times m$ initialized to the matrix with |x|
|
||||
entries.}*/
|
||||
|
|
@ -187,7 +190,8 @@ void range_initialize(RAIterator first, RAIterator last,
|
|||
template <class InputIterator>
|
||||
void range_initialize(InputIterator first, InputIterator last,
|
||||
std::forward_iterator_tag)
|
||||
{ typedef typename std::iterator_traits<InputIterator>::value_type value_type;
|
||||
{ typedef typename std::iterator_traits<InputIterator>::value_type
|
||||
value_type;
|
||||
std::vector<value_type> V(first,last);
|
||||
range_initialize(V.begin(),V.end(),std::random_access_iterator_tag());
|
||||
}
|
||||
|
|
@ -200,7 +204,7 @@ by the iterator range |[first,last)|. |\Mvar| is initialized to an $n
|
|||
\times m$ matrix with the columns as specified by $S$. \precond
|
||||
|Forward_iterator| has a value type |V| from which we require to
|
||||
provide a iterator type |V::const_iterator|, to have |V::value_type ==
|
||||
RT|.\\ Note that |Ivector| or |std::vector<RT,LA>| fulfill these
|
||||
NT|.\\ Note that |Ivector| or |std::vector<NT,LA>| fulfill these
|
||||
requirements.}*/
|
||||
{ range_initialize(first,last,
|
||||
std::iterator_traits<Forward_iterator>::iterator_category()); }
|
||||
|
|
@ -210,82 +214,110 @@ Imatrix(const std::vector< Vector >& A)
|
|||
be an array of $m$ column-vectors of common dimension $n$.
|
||||
|\Mvar| is initialized to an $n \times m$ matrix with the
|
||||
columns as specified by $A$. }*/
|
||||
{ range_initialize(A.begin(),A.end(),std::random_access_iterator_tag()); }
|
||||
{ range_initialize(A.begin(),A.end(),
|
||||
std::random_access_iterator_tag()); }
|
||||
|
||||
Imatrix(const Imatrix<_RT,_ALLOC>&);
|
||||
Imatrix(const Imatrix<_NT,_ALLOC>&);
|
||||
|
||||
Imatrix(const Ivector<_RT,_ALLOC>&);
|
||||
Imatrix(const Vector&);
|
||||
/* creates a $d \times 1$ matrix */
|
||||
Imatrix(int, int, RT**);
|
||||
Imatrix<_RT,_ALLOC>& operator=(const Imatrix<_RT,_ALLOC>&);
|
||||
|
||||
Imatrix(int, int, NT**);
|
||||
|
||||
Imatrix<_NT,_ALLOC>& operator=(const Imatrix<_NT,_ALLOC>&);
|
||||
|
||||
~Imatrix();
|
||||
|
||||
/*{\Moperations 1.7 3.5}*/
|
||||
|
||||
int row_dimension() const { return d1; }
|
||||
/*{\Mop returns $n$, the number of rows of |\Mvar|. }*/
|
||||
/*{\Mop returns $n$, the number of rows of |\Mvar|.}*/
|
||||
|
||||
int column_dimension() const { return d2; }
|
||||
/*{\Mop returns $m$, the number of columns of |\Mvar|. }*/
|
||||
/*{\Mop returns $m$, the number of columns of |\Mvar|.}*/
|
||||
|
||||
std::pair<int,int> dimension() const
|
||||
/*{\Mop returns $(m,n)$, the dimension pair of |\Mvar|.}*/
|
||||
{ return std::pair<int,int>(d1,d2); }
|
||||
|
||||
Vector& row(int i) const
|
||||
/*{\Mop returns the $i$-th row of |\Mvar| (an $m$ - vector).\\
|
||||
\precond $0 \le i \le n - 1$. }*/
|
||||
{
|
||||
LA_PRECOND((0<=i && i<d1), "Imatrix::row: index out of range.")
|
||||
CGAL_LA_PRECOND((0<=i && i<d1), "Imatrix::row: index out of range.")
|
||||
return *v[i];
|
||||
}
|
||||
|
||||
Vector column(int i) const;
|
||||
inline Vector column(int i) const;
|
||||
/*{\Mop returns the $i$-th column of |\Mvar| (an $n$ - vector).\\
|
||||
\precond $0 \le i \le m - 1$. }*/
|
||||
Ivector<_RT,_ALLOC> to_vector() const
|
||||
|
||||
Vector to_vector() const
|
||||
{
|
||||
LA_PRECOND((d2==1),
|
||||
CGAL_LA_PRECOND((d2==1),
|
||||
"Imatrix::to_vector: cannot make vector from matrix.")
|
||||
return column(0);
|
||||
}
|
||||
|
||||
friend Ivector<_RT,_ALLOC> to_vector(const Imatrix<RT,_ALLOC>& M)
|
||||
friend Ivector<_NT,_ALLOC> to_vector(const Imatrix<NT,_ALLOC>& M)
|
||||
{ return M.to_vector(); }
|
||||
|
||||
Ivector<_RT,_ALLOC>& operator[](int i) const
|
||||
Ivector<_NT,_ALLOC>& operator[](int i) const
|
||||
{
|
||||
LA_PRECOND((0<=i && i<d1),
|
||||
CGAL_LA_PRECOND((0<=i && i<d1),
|
||||
"Imatrix::operator[]: index out of range.")
|
||||
return row(i);
|
||||
}
|
||||
|
||||
RT& operator()(int i, int j)
|
||||
NT& operator()(int i, int j)
|
||||
/*{\Mfunop returns $M_{ i,j }$. \\
|
||||
\precond $0\le i\le n - 1$ and $0\le j\le m - 1$. }*/
|
||||
\precond $0\le i\le n - 1$ and $0\le j\le m - 1$. }*/
|
||||
{
|
||||
LA_PRECOND((0<=i && i<d1),
|
||||
CGAL_LA_PRECOND((0<=i && i<d1),
|
||||
"Imatrix::operator(): row index out of range.")
|
||||
LA_PRECOND((0<=j && j<d2),
|
||||
CGAL_LA_PRECOND((0<=j && j<d2),
|
||||
"Imatrix::operator(): column index out of range.")
|
||||
return elem(i,j);
|
||||
}
|
||||
|
||||
RT operator()(int i, int j) const
|
||||
NT operator()(int i, int j) const
|
||||
{
|
||||
LA_PRECOND((0<=i && i<d1),
|
||||
CGAL_LA_PRECOND((0<=i && i<d1),
|
||||
"Imatrix::operator(): row index out of range.")
|
||||
LA_PRECOND((0<=j && j<d2),
|
||||
CGAL_LA_PRECOND((0<=j && j<d2),
|
||||
"Imatrix::operator(): column index out of range.")
|
||||
return elem(i,j);
|
||||
}
|
||||
|
||||
bool operator==(const Imatrix<_RT,_ALLOC>& M1) const;
|
||||
void swap_columns(int i, int j)
|
||||
/*{\Mop swaps columns $i$ and $j$.}*/
|
||||
{ CGAL_assertion(0<=i && i<d2 && 0<=j && j<d2);
|
||||
for(int l = 0; l < d1; l++) std::swap(elem(l,i),elem(l,j));
|
||||
}
|
||||
|
||||
void swap_rows(int i, int j)
|
||||
/*{\Mop swaps rows $i$ and $j$.}*/
|
||||
{ CGAL_assertion(0<=i && i<d1 && 0<=j && j<d1);
|
||||
std::swap(v[i],v[j]);
|
||||
}
|
||||
|
||||
Row_iterator row_begin(int i) { return v[i]->begin(); }
|
||||
Row_iterator row_end(int i) { return v[i]->end(); }
|
||||
|
||||
Row_const_iterator row_begin(int i) const { return v[i]->begin(); }
|
||||
Row_const_iterator row_end(int i) const { return v[i]->end(); }
|
||||
|
||||
|
||||
bool operator==(const Imatrix<_NT,_ALLOC>& M1) const;
|
||||
/*{\Mbinop Test for equality. }*/
|
||||
|
||||
bool operator!=(const Imatrix<_RT,_ALLOC>& M1) const
|
||||
bool operator!=(const Imatrix<_NT,_ALLOC>& M1) const
|
||||
/*{\Mbinop Test for inequality. }*/
|
||||
{ return !(*this == M1); }
|
||||
|
||||
/*{\Mtext \headerline{Arithmetic Operators}}*/
|
||||
/*{\Mtext
|
||||
\settowidth{\typewidth}{|Imatrix<RT,LA>m|}
|
||||
\settowidth{\typewidth}{|Imatrix<NT,LA>m|}
|
||||
\addtolength{\typewidth}{\colsep}
|
||||
\callwidth2cm
|
||||
\computewidths
|
||||
|
|
@ -295,60 +327,60 @@ bool operator!=(const Imatrix<_RT,_ALLOC>& M1) const
|
|||
}
|
||||
}*/
|
||||
|
||||
Imatrix<_RT,_ALLOC> operator+ (const Imatrix<_RT,_ALLOC>& M1);
|
||||
Imatrix<_NT,_ALLOC> operator+ (const Imatrix<_NT,_ALLOC>& M1);
|
||||
/*{\Mbinop Addition. \precond \dimeq.}*/
|
||||
|
||||
Imatrix<_RT,_ALLOC> operator- (const Imatrix<_RT,_ALLOC>& M1);
|
||||
Imatrix<_NT,_ALLOC> operator- (const Imatrix<_NT,_ALLOC>& M1);
|
||||
/*{\Mbinop Subtraction. \precond \dimeq.}*/
|
||||
|
||||
Imatrix<_RT,_ALLOC> operator-(); // unary
|
||||
Imatrix<_NT,_ALLOC> operator-(); // unary
|
||||
/*{\Munop Negation.}*/
|
||||
|
||||
Imatrix<_RT,_ALLOC>& operator-=(const Imatrix<_RT,_ALLOC>&);
|
||||
Imatrix<_NT,_ALLOC>& operator-=(const Imatrix<_NT,_ALLOC>&);
|
||||
|
||||
Imatrix<_RT,_ALLOC>& operator+=(const Imatrix<_RT,_ALLOC>&);
|
||||
Imatrix<_NT,_ALLOC>& operator+=(const Imatrix<_NT,_ALLOC>&);
|
||||
|
||||
Imatrix<_RT,_ALLOC>
|
||||
operator*(const Imatrix<_RT,_ALLOC>& M1) const;
|
||||
Imatrix<_NT,_ALLOC>
|
||||
operator*(const Imatrix<_NT,_ALLOC>& M1) const;
|
||||
/*{\Mbinop Multiplication. \precond \\
|
||||
|\Mvar.column_dimension() = M1.row_dimension()|. }*/
|
||||
|
||||
Ivector<_RT,_ALLOC>
|
||||
operator*(const Ivector<_RT,_ALLOC>& vec) const
|
||||
{ return ((*this) * Imatrix<_RT,_ALLOC>(vec)).to_vector(); }
|
||||
Ivector<_NT,_ALLOC>
|
||||
operator*(const Ivector<_NT,_ALLOC>& vec) const
|
||||
{ return ((*this) * Imatrix<_NT,_ALLOC>(vec)).to_vector(); }
|
||||
/*{\Mbinop Multiplication with vector. \precond \\
|
||||
|\Mvar.column_dimension() = vec.dimension()|.}*/
|
||||
|\Mvar.column_dimension() = vec.dimension()|.}*/
|
||||
|
||||
Imatrix<_RT,_ALLOC> compmul(const RT& x) const;
|
||||
Imatrix<_NT,_ALLOC> compmul(const NT& x) const;
|
||||
|
||||
static int compare(const Imatrix<_RT,_ALLOC>& M1,
|
||||
const Imatrix<_RT,_ALLOC>& M2);
|
||||
static int compare(const Imatrix<_NT,_ALLOC>& M1,
|
||||
const Imatrix<_NT,_ALLOC>& M2);
|
||||
|
||||
}; // end of class
|
||||
|
||||
/*{\Xtext \headerline{Input and Output}}*/
|
||||
|
||||
template <class RT, class A>
|
||||
std::ostream& operator<<(std::ostream& os, const Imatrix<RT,A>& M);
|
||||
template <class NT, class A>
|
||||
std::ostream& operator<<(std::ostream& os, const Imatrix<NT,A>& M);
|
||||
/*{\Xbinopfunc writes matrix |\Mvar| row by row to the output stream |os|.}*/
|
||||
|
||||
template <class RT, class A>
|
||||
std::istream& operator>>(std::istream& is, Imatrix<RT,A>& M);
|
||||
template <class NT, class A>
|
||||
std::istream& operator>>(std::istream& is, Imatrix<NT,A>& M);
|
||||
/*{\Xbinopfunc reads matrix |\Mvar| row by row from the input stream |is|.}*/
|
||||
|
||||
|
||||
/*{\Mimplementation
|
||||
The data type |\Mname| is implemented by two-dimensional arrays of
|
||||
variables of type |RT|. The memory layout is row oriented. Operation
|
||||
variables of type |NT|. The memory layout is row oriented. Operation
|
||||
|column| takes time $O(n)$, |row|, |dim1|, |dim2| take constant time,
|
||||
and all other operations take time $O(nm)$. The space requirement is
|
||||
$O(nm)$.}*/
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(int dim) : d1(dim),d2(dim)
|
||||
{
|
||||
LA_PRECOND((dim >= 0), "Imatrix::constructor: negative dimension.")
|
||||
CGAL_LA_PRECOND((dim >= 0), "Imatrix::constructor: negative dimension.")
|
||||
if (d1 > 0) {
|
||||
allocate_mat_space(v,d1);
|
||||
for (int i=0; i<d1; i++)
|
||||
|
|
@ -357,11 +389,11 @@ Imatrix(int dim) : d1(dim),d2(dim)
|
|||
v = (Vector**)0;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(int dim1, int dim2) : d1(dim1),d2(dim2)
|
||||
{
|
||||
LA_PRECOND((dim1>=0 && dim2>=0),
|
||||
CGAL_LA_PRECOND((dim1>=0 && dim2>=0),
|
||||
"Imatrix::constructor: negative dimension.")
|
||||
|
||||
if (d1 > 0) {
|
||||
|
|
@ -372,26 +404,41 @@ Imatrix(int dim1, int dim2) : d1(dim1),d2(dim2)
|
|||
v = (Vector**)0;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
Imatrix(int dim, const Identity&, const RT& x) : d1(dim),d2(dim)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(std::pair<int,int> p) : d1(p.first),d2(p.second)
|
||||
{
|
||||
LA_PRECOND((dim >= 0), "Imatrix::constructor: negative dimension.")
|
||||
CGAL_LA_PRECOND((d1>=0 && d2>=0),
|
||||
"Imatrix::constructor: negative dimension.")
|
||||
if (d1 > 0) {
|
||||
allocate_mat_space(v,d1);
|
||||
for (int i=0; i<d1; i++)
|
||||
v[i] = new Vector(d2);
|
||||
if (x!=RT(0)) for (int i=0; i<d1; i++) elem(i,i)=x;
|
||||
} else
|
||||
v = (Vector**)0;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
Imatrix(int dim1, int dim2, const Initialize&, const RT& x) :
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(int dim, const Identity&, const NT& x) : d1(dim),d2(dim)
|
||||
{
|
||||
CGAL_LA_PRECOND((dim >= 0),
|
||||
"matrix::constructor: negative dimension.")
|
||||
if (d1 > 0) {
|
||||
allocate_mat_space(v,d1);
|
||||
for (int i=0; i<d1; i++)
|
||||
v[i] = new Vector(d2);
|
||||
if (x!=NT(0)) for (int i=0; i<d1; i++) elem(i,i)=x;
|
||||
} else
|
||||
v = (Vector**)0;
|
||||
}
|
||||
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(int dim1, int dim2, const Initialize&, const NT& x) :
|
||||
d1(dim1),d2(dim2)
|
||||
{
|
||||
LA_PRECOND((dim1>=0 && dim2>=0),
|
||||
CGAL_LA_PRECOND((dim1>=0 && dim2>=0),
|
||||
"Imatrix::constructor: negative dimension.")
|
||||
|
||||
if (d1 > 0) {
|
||||
|
|
@ -402,10 +449,9 @@ Imatrix(int dim1, int dim2, const Initialize&, const RT& x) :
|
|||
v = (Vector**)0;
|
||||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
Imatrix(const Imatrix<RT,A>& p) : d1(p.d1),d2(p.d2)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(const Imatrix<NT,A>& p) : d1(p.d1),d2(p.d2)
|
||||
{
|
||||
if (d1 > 0) {
|
||||
allocate_mat_space(v,d1);
|
||||
|
|
@ -413,43 +459,45 @@ Imatrix(const Imatrix<RT,A>& p) : d1(p.d1),d2(p.d2)
|
|||
v[i] = new Vector(*p.v[i]);
|
||||
}
|
||||
else
|
||||
v = (Ivector<RT,A>**)0;
|
||||
v = (Ivector<NT,A>**)0;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
Imatrix(const Ivector<RT,A>& vec) : d1(vec.dim),d2(1)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(const Vector& vec) : d1(vec.dim),d2(1)
|
||||
{
|
||||
if (d1>0)
|
||||
allocate_mat_space(v,d1);
|
||||
else
|
||||
v = (Ivector<RT,A>**)0;
|
||||
v = (Ivector<NT,A>**)0;
|
||||
for(int i = 0; i < d1; i++) {
|
||||
v[i] = new Vector(1);
|
||||
elem(i,0) = vec[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
Imatrix(int dim1, int dim2, RT** p) : d1(dim1),d2(dim2)
|
||||
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
Imatrix(int dim1, int dim2, NT** p) : d1(dim1),d2(dim2)
|
||||
{
|
||||
LA_PRECOND((dim1 >= 0 && dim2 >= 0),
|
||||
CGAL_LA_PRECOND((dim1 >= 0 && dim2 >= 0),
|
||||
"Imatrix::constructor: negative dimension.")
|
||||
if (d1 > 0) {
|
||||
allocate_mat_space(v,d1);
|
||||
for(int i=0; i<d1; i++) {
|
||||
v[i] = new Ivector<RT,A>(d2);
|
||||
v[i] = new Ivector<NT,A>(d2);
|
||||
for(int j=0; j<d2; j++)
|
||||
elem(i,j) = p[i][j];
|
||||
}
|
||||
} else
|
||||
v = (Ivector<RT,A>**)0;
|
||||
v = (Ivector<NT,A>**)0;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>& Imatrix<RT,A>::
|
||||
operator=(const Imatrix<RT,A>& mat)
|
||||
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>& Imatrix<NT,A>::
|
||||
operator=(const Imatrix<NT,A>& mat)
|
||||
{
|
||||
register int i,j;
|
||||
if (d1 != mat.d1 || d2 != mat.d2) {
|
||||
|
|
@ -470,8 +518,8 @@ operator=(const Imatrix<RT,A>& mat)
|
|||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::
|
||||
~Imatrix()
|
||||
{
|
||||
if (v) {
|
||||
|
|
@ -481,13 +529,11 @@ Imatrix<RT,A>::
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> Imatrix<RT,A>::
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> Imatrix<NT,A>::
|
||||
column(int i) const
|
||||
{
|
||||
LA_PRECOND((i>=0 && i<d2),
|
||||
CGAL_LA_PRECOND((i>=0 && i<d2),
|
||||
"Imatrix::column: index out of range.")
|
||||
|
||||
Vector result(d1);
|
||||
|
|
@ -496,9 +542,9 @@ column(int i) const
|
|||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
bool Imatrix<RT,A>::
|
||||
operator==(const Imatrix<RT,A>& x) const
|
||||
template <class NT, class A>
|
||||
bool Imatrix<NT,A>::
|
||||
operator==(const Imatrix<NT,A>& x) const
|
||||
{
|
||||
register int i,j;
|
||||
if (d1 != x.d1 || d2 != x.d2)
|
||||
|
|
@ -511,47 +557,47 @@ operator==(const Imatrix<RT,A>& x) const
|
|||
return true;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> Imatrix<RT,A>::
|
||||
operator+ (const Imatrix<RT,A>& mat)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> Imatrix<NT,A>::
|
||||
operator+ (const Imatrix<NT,A>& mat)
|
||||
{
|
||||
register int i,j;
|
||||
check_dimensions(mat);
|
||||
Imatrix<RT,A> result(d1,d2);
|
||||
Imatrix<NT,A> result(d1,d2);
|
||||
for(i=0; i<d1; i++)
|
||||
for(j=0; j<d2; j++)
|
||||
result.elem(i,j) = elem(i,j) + mat.elem(i,j);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> Imatrix<RT,A>::
|
||||
operator- (const Imatrix<RT,A>& mat)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> Imatrix<NT,A>::
|
||||
operator- (const Imatrix<NT,A>& mat)
|
||||
{
|
||||
register int i,j;
|
||||
check_dimensions(mat);
|
||||
Imatrix<RT,A> result(d1,d2);
|
||||
Imatrix<NT,A> result(d1,d2);
|
||||
for(i=0; i<d1; i++)
|
||||
for(j=0; j<d2; j++)
|
||||
result.elem(i,j) = elem(i,j) - mat.elem(i,j);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> Imatrix<RT,A>::
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> Imatrix<NT,A>::
|
||||
operator- () // unary
|
||||
{
|
||||
register int i,j;
|
||||
Imatrix<RT,A> result(d1,d2);
|
||||
Imatrix<NT,A> result(d1,d2);
|
||||
for(i=0; i<d1; i++)
|
||||
for(j=0; j<d2; j++)
|
||||
result.elem(i,j) = -elem(i,j);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>& Imatrix<RT,A>::
|
||||
operator-= (const Imatrix<RT,A>& mat)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>& Imatrix<NT,A>::
|
||||
operator-= (const Imatrix<NT,A>& mat)
|
||||
{
|
||||
register int i,j;
|
||||
check_dimensions(mat);
|
||||
|
|
@ -561,9 +607,9 @@ operator-= (const Imatrix<RT,A>& mat)
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>& Imatrix<RT,A>::
|
||||
operator+= (const Imatrix<RT,A>& mat)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>& Imatrix<NT,A>::
|
||||
operator+= (const Imatrix<NT,A>& mat)
|
||||
{
|
||||
register int i,j;
|
||||
check_dimensions(mat);
|
||||
|
|
@ -573,14 +619,14 @@ operator+= (const Imatrix<RT,A>& mat)
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> Imatrix<RT,A>::
|
||||
operator*(const Imatrix<RT,A>& mat) const
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> Imatrix<NT,A>::
|
||||
operator*(const Imatrix<NT,A>& mat) const
|
||||
{
|
||||
LA_PRECOND((d2==mat.d1),
|
||||
CGAL_LA_PRECOND((d2==mat.d1),
|
||||
"Imatrix::operator*: incompatible matrix types.")
|
||||
|
||||
Imatrix<RT,A> result(d1, mat.d2);
|
||||
Imatrix<NT,A> result(d1, mat.d2);
|
||||
register int i,j;
|
||||
|
||||
for (i=0; i<mat.d2; i++)
|
||||
|
|
@ -589,12 +635,12 @@ operator*(const Imatrix<RT,A>& mat) const
|
|||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> Imatrix<RT,A>::
|
||||
compmul(const RT& f) const
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> Imatrix<NT,A>::
|
||||
compmul(const NT& f) const
|
||||
{
|
||||
register int i,j;
|
||||
Imatrix<RT,A> result(d1,d2);
|
||||
Imatrix<NT,A> result(d1,d2);
|
||||
for(i=0; i<d1; i++)
|
||||
for(j=0; j<d2; j++)
|
||||
result.elem(i,j) = elem(i,j) *f;
|
||||
|
|
@ -602,28 +648,28 @@ compmul(const RT& f) const
|
|||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> operator*(const Imatrix<RT,A>& M, const RT& x)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> operator*(const Imatrix<NT,A>& M, const NT& x)
|
||||
{ return M.compmul(x); }
|
||||
/*{\Mbinopfunc Multiplication of every entry with |x|. }*/
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> operator*(const Imatrix<RT,A>& M, int x)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> operator*(const Imatrix<NT,A>& M, int x)
|
||||
{ return M.compmul(x); }
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> operator*(const RT& x, const Imatrix<RT,A>& M)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> operator*(const NT& x, const Imatrix<NT,A>& M)
|
||||
{ return M.compmul(x); }
|
||||
/*{\Mbinopfunc Multiplication of every entry with |x|. }*/
|
||||
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A> operator*(int x, const Imatrix<RT,A>& M)
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A> operator*(int x, const Imatrix<NT,A>& M)
|
||||
{ return M.compmul(x); }
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
int Imatrix<RT,A>::
|
||||
compare(const Imatrix<RT,A>& M1, const Imatrix<RT,A>& M2)
|
||||
template <class NT, class A>
|
||||
int Imatrix<NT,A>::
|
||||
compare(const Imatrix<NT,A>& M1, const Imatrix<NT,A>& M2)
|
||||
{
|
||||
register int i;
|
||||
int res;
|
||||
|
|
@ -634,49 +680,63 @@ compare(const Imatrix<RT,A>& M1, const Imatrix<RT,A>& M2)
|
|||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
std::ostream& operator<<(std::ostream& O, const Imatrix<RT,A>& M)
|
||||
template <class NT, class A>
|
||||
std::ostream& operator<<(std::ostream& os, const Imatrix<NT,A>& M)
|
||||
{
|
||||
/* syntax: d1 d2
|
||||
x_0,0 ... x_0,d1-1
|
||||
d2-times
|
||||
x_d2,0 ... x_d2,d1-1 */
|
||||
O << M.row_dimension() << ' ' << M.column_dimension() << std::endl;
|
||||
for (register int i=0; i < M.row_dimension(); i++) {
|
||||
for (register int j=0; j < M.column_dimension(); j++)
|
||||
O << M(i,j) << " ";
|
||||
O << std::endl;
|
||||
|
||||
CGAL::print_d<NT> prt(&os);
|
||||
if (os.iword(IO::mode)==IO::PRETTY) os << "LA::Matrix(";
|
||||
prt(M.row_dimension());
|
||||
prt(M.column_dimension());
|
||||
if (os.iword(IO::mode)==IO::PRETTY) { os << " [\n"; prt.reset(); }
|
||||
for (register int i=0; i<M.row_dimension(); i++) {
|
||||
std::for_each(M.row(i).begin(),M.row(i).end(),prt);
|
||||
if (i != M.row_dimension() && os.iword(IO::mode)==IO::PRETTY)
|
||||
{ prt.reset(); os << ",\n";}
|
||||
}
|
||||
return O;
|
||||
if (os.iword(IO::mode)==IO::PRETTY) os << "])";
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
std::istream& operator>>(std::istream& in, Imatrix<RT,A>& M)
|
||||
template <class NT, class A>
|
||||
std::istream& operator>>(std::istream& is, Imatrix<NT,A>& M)
|
||||
{
|
||||
/* syntax: d1 d2
|
||||
x_0,0 ... x_0,d1-1
|
||||
d2-times
|
||||
x_d2,0 ... x_d2,d1-1 */
|
||||
|
||||
int dim1 = 0, dim2 = 0;
|
||||
if (!(in >> dim1 >> dim2))
|
||||
return in;
|
||||
if (M.row_dimension() != dim1 || M.column_dimension() != dim2)
|
||||
M = Imatrix<RT,A>(dim1,dim2);
|
||||
|
||||
for (register int i=0; i<dim1; i++)
|
||||
for (register int j=0; j<dim2; j++)
|
||||
if (!(in >> M(i,j)))
|
||||
return in;
|
||||
return in;
|
||||
int cdim, rdim;
|
||||
switch(is.iword(IO::mode)) {
|
||||
case IO::BINARY :
|
||||
CGAL::read(is,rdim);
|
||||
CGAL::read(is,cdim);
|
||||
for (register int i=0; i<rdim*cdim; ++i)
|
||||
CGAL::read(is,M(i/rdim,i%cdim));
|
||||
break;
|
||||
case IO::ASCII :
|
||||
is >> rdim >> cdim;
|
||||
M = Imatrix<NT,A>(rdim,cdim);
|
||||
for (register int i=0; i<rdim*cdim; ++i)
|
||||
is >> M(i/rdim,i%cdim);
|
||||
break;
|
||||
default:
|
||||
std::cerr<<"\nStream must be in ascii or binary mode"<<std::endl;
|
||||
break;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
template <class RT, class A>
|
||||
Imatrix<RT,A>::allocator_type Imatrix<RT,A>::MM;
|
||||
template <class NT, class A>
|
||||
Imatrix<NT,A>::allocator_type Imatrix<NT,A>::MM;
|
||||
#endif
|
||||
|
||||
|
||||
LA_END_NAMESPACE
|
||||
#endif // LINALG_IMATRIX_H
|
||||
CGAL_END_NAMESPACE
|
||||
#endif // CGAL_IMATRIX_H
|
||||
|
||||
|
|
|
|||
|
|
@ -33,43 +33,36 @@
|
|||
// debugging and templatization: M. Seel
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
#ifndef LINALG_IVECTOR_H
|
||||
#define LINALG_IVECTOR_H
|
||||
#ifndef CGAL_IVECTOR_H
|
||||
#define CGAL_IVECTOR_H
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/memory.h>
|
||||
#include <CGAL/Kernel_d/d_utils.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#define LA_BEGIN_NAMESPACE namespace CGAL {
|
||||
#define LA_END_NAMESPACE } // namespace CGAL
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
LA_BEGIN_NAMESPACE
|
||||
|
||||
template <class RT, class A = CGAL_ALLOCATOR(RT) >
|
||||
template <class NT, class A = CGAL_ALLOCATOR(NT) >
|
||||
class Imatrix;
|
||||
template <class RT, class A = CGAL_ALLOCATOR(RT) >
|
||||
template <class NT, class A = CGAL_ALLOCATOR(NT) >
|
||||
class Ivector;
|
||||
|
||||
#if 0
|
||||
#define LA_PRECOND(cond,s)\
|
||||
if (!(cond)) {\
|
||||
std::cout << "precondition " << #cond << " failed" << std::endl;\
|
||||
std::cout << s << std::endl; exit(1); }
|
||||
#define ERROR_HANDLER(n,s)(std::cerr << s << std::endl, exit(n))
|
||||
#else
|
||||
#define LA_PRECOND(cond,s) CGAL_assertion_msg((cond),s);
|
||||
#define CGAL_LA_PRECOND(cond,s) CGAL_assertion_msg((cond),s);
|
||||
#define ERROR_HANDLER(n,s) CGAL_assertion_msg(!(n),s)
|
||||
#endif
|
||||
|
||||
|
||||
/*{\Msubst
|
||||
<>#
|
||||
<_RT,_ALLOC>#<RT,LA>
|
||||
<_NT,_ALLOC>#<NT>
|
||||
Ivector#Vector
|
||||
Imatrix#Matrix
|
||||
}*/
|
||||
|
||||
/*{\Moptions print_title=yes}*/
|
||||
/*{\Moptions outfile=Ivector.man}*/
|
||||
|
||||
/*{\Mtext \headerline{Common Notation}
|
||||
|
|
@ -84,25 +77,23 @@ iterators to input iterators. If we index the tuple as above then we
|
|||
require that $|++|^{(d)}|first == last|$ (note that |last| points
|
||||
beyond the last element to be accepted).}*/
|
||||
|
||||
/*{\Manpage {Ivector}{RT}{Vectors with RT Entries}{v}}*/
|
||||
/*{\Manpage {Vector}{NT}{Vectors with NT Entries}{v}}*/
|
||||
|
||||
template <class _RT, class _ALLOC>
|
||||
template <class _NT, class _ALLOC>
|
||||
class Ivector
|
||||
{
|
||||
|
||||
/*{\Mdefinition An instance of data type |Ivector| is a vector of
|
||||
variables of type |RT|, the so-called ring type. Together with the
|
||||
type |Imatrix| it realizes the basic operations of linear
|
||||
algebra. Internal correctness tests are executed if compiled with the
|
||||
flag [[CGAL_LA_SELFTEST]].}*/
|
||||
variables of number type |NT|. Together with the type |Imatrix| it
|
||||
realizes the basic operations of linear algebra. Internal correctness
|
||||
tests are executed if compiled with the flag [[CGAL_LA_SELFTEST]].}*/
|
||||
|
||||
public:
|
||||
|
||||
/*{\Mtypes 5.5}*/
|
||||
typedef _RT* pointer;
|
||||
typedef const _RT* const_pointer;
|
||||
typedef _NT* pointer;
|
||||
typedef const _NT* const_pointer;
|
||||
|
||||
typedef _RT RT;
|
||||
typedef _NT NT;
|
||||
/*{\Mtypemember the ring type of the components.}*/
|
||||
|
||||
typedef pointer iterator;
|
||||
|
|
@ -115,46 +106,43 @@ class Initialize {};
|
|||
/*{\Mtypemember a tag class for homogeneous initialization}*/
|
||||
|
||||
protected:
|
||||
|
||||
friend class Imatrix<_RT,_ALLOC>;
|
||||
RT* v;
|
||||
friend class Imatrix<_NT,_ALLOC>;
|
||||
NT* v;
|
||||
int dim;
|
||||
|
||||
typedef _ALLOC allocator_type;
|
||||
static allocator_type MM;
|
||||
|
||||
inline void allocate_vec_space(RT*& vi, int di)
|
||||
inline void allocate_vec_space(NT*& vi, int di)
|
||||
{
|
||||
/* We use this procedure to allocate memory. We first get an appropriate
|
||||
piece of memory from the allocator and then initialize each cell
|
||||
by an inplace new. */
|
||||
|
||||
vi = MM.allocate(di);
|
||||
RT* p = vi + di - 1;
|
||||
while (p >= vi) { new (p) RT(0); p--; }
|
||||
NT* p = vi + di - 1;
|
||||
while (p >= vi) { new (p) NT(0); p--; }
|
||||
}
|
||||
|
||||
inline void deallocate_vec_space(RT*& vi, int di)
|
||||
inline void deallocate_vec_space(NT*& vi, int di)
|
||||
{
|
||||
/* We use this procedure to deallocate memory. We have to free it by
|
||||
the allocator scheme. We first call the destructor for type RT for each
|
||||
the allocator scheme. We first call the destructor for type NT for each
|
||||
cell of the array and then return the piece of memory to the memory
|
||||
manager. */
|
||||
|
||||
RT* p = vi + di - 1;
|
||||
while (p >= vi) { p->~RT(); p--; }
|
||||
NT* p = vi + di - 1;
|
||||
while (p >= vi) { p->~NT(); p--; }
|
||||
MM.deallocate(vi, di);
|
||||
vi = (RT*)0;
|
||||
vi = (NT*)0;
|
||||
}
|
||||
|
||||
inline void
|
||||
check_dimensions(const Ivector<_RT,_ALLOC>& vec) const
|
||||
check_dimensions(const Ivector<_NT,_ALLOC>& vec) const
|
||||
{
|
||||
LA_PRECOND((dim == vec.dim), "Ivector::check_dimensions:\
|
||||
CGAL_LA_PRECOND((dim == vec.dim), "Ivector::check_dimensions:\
|
||||
object dimensions disagree.")
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/*{\Mcreation v 3}*/
|
||||
|
|
@ -163,22 +151,23 @@ Ivector(int d = 0)
|
|||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname|.
|
||||
|\Mvar| is initialized to a vector of dimension $d$.}*/
|
||||
{
|
||||
LA_PRECOND( d >= 0 , "Ivector::constructor: negative dimension.")
|
||||
CGAL_LA_PRECOND( d >= 0 ,
|
||||
"Ivector::constructor: negative dimension.")
|
||||
dim = d;
|
||||
v = (RT*)0;
|
||||
v = (NT*)0;
|
||||
if (dim > 0){
|
||||
allocate_vec_space(v,dim);
|
||||
while (d--) v[d] = RT(0);
|
||||
while (d--) v[d] = NT(0);
|
||||
}
|
||||
}
|
||||
|
||||
Ivector(int d, const Initialize&, const RT& x)
|
||||
Ivector(int d, const Initialize&, const NT& x)
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname|.
|
||||
|\Mvar| is initialized to a vector of dimension $d$ with entries |x|.}*/
|
||||
{
|
||||
LA_PRECOND( d >= 0 , "Ivector::constructor: negative dimension.")
|
||||
CGAL_LA_PRECOND( d >= 0 , "Ivector::constructor: negative dimension.")
|
||||
dim = d;
|
||||
v = (RT*)0;
|
||||
v = (NT*)0;
|
||||
if (dim > 0){
|
||||
allocate_vec_space(v,dim);
|
||||
while (d--) v[d] = x;
|
||||
|
|
@ -189,7 +178,7 @@ template <class Forward_iterator>
|
|||
Ivector(Forward_iterator first, Forward_iterator last)
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname|;
|
||||
|\Mvar| is initialized to the vector with entries
|
||||
|set [first,last)|. \precond |Forward_iterator| has value type |RT|.}*/
|
||||
|set [first,last)|. \precond |Forward_iterator| has value type |NT|.}*/
|
||||
{ dim = std::distance(first,last);
|
||||
allocate_vec_space(v,dim);
|
||||
iterator it = begin();
|
||||
|
|
@ -197,22 +186,22 @@ Ivector(Forward_iterator first, Forward_iterator last)
|
|||
}
|
||||
|
||||
private:
|
||||
void init(int d, const RT& x0, const RT& x1, const RT& x2=0, const RT& x3=0)
|
||||
void init(int d, const NT& x0, const NT& x1, const NT& x2=0, const NT& x3=0)
|
||||
{ dim = d; allocate_vec_space(v,dim);
|
||||
v[0]=x0; v[1]=x1; ( d>2 ? (v[2]=x2) : 0); ( d>3 ? (v[3]=x3) : 0);
|
||||
}
|
||||
public:
|
||||
|
||||
Ivector(const RT& a, const RT& b) { init(2,a,b); }
|
||||
Ivector(const NT& a, const NT& b) { init(2,a,b); }
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname|.
|
||||
|\Mvar| is initialized to the two-dimensional vector $(a,b)$.}*/
|
||||
|
||||
Ivector(const RT& a, const RT& b, const RT& c) { init(3,a,b,c); }
|
||||
Ivector(const NT& a, const NT& b, const NT& c) { init(3,a,b,c); }
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname|.
|
||||
|\Mvar| is initialized to the three-dimensional vector
|
||||
$(a,b,c)$.}*/
|
||||
|
||||
Ivector(const RT& a, const RT& b, const RT& c, const RT& d)
|
||||
Ivector(const NT& a, const NT& b, const NT& c, const NT& d)
|
||||
/*{\Mcreate creates an instance |\Mvar| of type |\Mname|;
|
||||
|\Mvar| is initialized to the four-dimensional vector
|
||||
$(a,b,c,d)$.}*/
|
||||
|
|
@ -223,15 +212,15 @@ Ivector(int a, int b, int c) { init(3,a,b,c); }
|
|||
Ivector(int a, int b, int c, int d) { init(4,a,b,c,d); }
|
||||
|
||||
|
||||
Ivector(const Ivector<_RT,_ALLOC>& p)
|
||||
Ivector(const Ivector<_NT,_ALLOC>& p)
|
||||
{ dim = p.dim;
|
||||
if (dim > 0) allocate_vec_space(v,dim);
|
||||
else v = (RT*)0;
|
||||
else v = (NT*)0;
|
||||
for(int i=0; i<dim; i++) { v[i] = p.v[i]; }
|
||||
}
|
||||
|
||||
|
||||
Ivector<_RT,_ALLOC>& operator=(const Ivector<_RT,_ALLOC>& vec)
|
||||
Ivector<_NT,_ALLOC>& operator=(const Ivector<_NT,_ALLOC>& vec)
|
||||
{
|
||||
register int n = vec.dim;
|
||||
if (n != dim) {
|
||||
|
|
@ -239,7 +228,7 @@ Ivector<_RT,_ALLOC>& operator=(const Ivector<_RT,_ALLOC>& vec)
|
|||
dim=n;
|
||||
}
|
||||
if (n > 0) allocate_vec_space(v,n);
|
||||
else v = (RT*)0;
|
||||
else v = (NT*)0;
|
||||
|
||||
while (n--) v[n] = vec.v[n];
|
||||
return *this;
|
||||
|
|
@ -250,47 +239,51 @@ Ivector<_RT,_ALLOC>& operator=(const Ivector<_RT,_ALLOC>& vec)
|
|||
|
||||
/*{\Moperations 3 3}*/
|
||||
|
||||
|
||||
int dimension() const { return dim; }
|
||||
/*{\Mop returns the dimension of |\Mvar|.}*/
|
||||
|
||||
bool is_zero() const
|
||||
/*{\Mop returns true iff |\Mvar| is the zero vector.}*/
|
||||
{ for(int i=0; i<dim; ++i) if (v[i]!=NT(0)) return false;
|
||||
return true; }
|
||||
|
||||
RT& operator[](int i)
|
||||
NT& operator[](int i)
|
||||
/*{\Marrop returns $i$-th component of |\Mvar|.\\
|
||||
\precond $0\le i \le |v.dimension()-1|$. }*/
|
||||
{ LA_PRECOND((0<=i && i<dim),
|
||||
{ CGAL_LA_PRECOND((0<=i && i<dim),
|
||||
"Ivector::operator[]: index out of range.")
|
||||
return v[i];
|
||||
}
|
||||
|
||||
RT operator[](int i) const
|
||||
{ LA_PRECOND((0<=i && i<dim),
|
||||
NT operator[](int i) const
|
||||
{ CGAL_LA_PRECOND((0<=i && i<dim),
|
||||
"Ivector::operator[]: index out of range.")
|
||||
return v[i];
|
||||
}
|
||||
|
||||
Ivector<_RT,_ALLOC>& operator+=(const Ivector<_RT,_ALLOC>& v1);
|
||||
Ivector<_NT,_ALLOC>& operator+=(const Ivector<_NT,_ALLOC>& v1);
|
||||
/*{\Mbinop Addition plus assignment. \precond\\
|
||||
|v.dimension() == v1.dimension()|.}*/
|
||||
|
||||
Ivector<_RT,_ALLOC>& operator-=(const Ivector<_RT,_ALLOC>& v1);
|
||||
Ivector<_NT,_ALLOC>& operator-=(const Ivector<_NT,_ALLOC>& v1);
|
||||
/*{\Mbinop Subtraction plus assignment. \precond\\
|
||||
|v.dimension() == v1.dimension()|.}*/
|
||||
|
||||
Ivector<_RT,_ALLOC> operator+(const Ivector<_RT,_ALLOC>& v1) const;
|
||||
Ivector<_NT,_ALLOC> operator+(const Ivector<_NT,_ALLOC>& v1) const;
|
||||
/*{\Mbinop Addition. \precond\\
|
||||
|v.dimension() == v1.dimension()|.}*/
|
||||
|
||||
Ivector<_RT,_ALLOC> operator-(const Ivector<_RT,_ALLOC>& v1) const;
|
||||
Ivector<_NT,_ALLOC> operator-(const Ivector<_NT,_ALLOC>& v1) const;
|
||||
/*{\Mbinop Subtraction. \precond\\
|
||||
|v.dimension() = v1.dimension()|.}*/
|
||||
|
||||
RT operator*(const Ivector<_RT,_ALLOC>& v1) const;
|
||||
NT operator*(const Ivector<_NT,_ALLOC>& v1) const;
|
||||
/*{\Mbinop Inner Product. \precond\\
|
||||
|v.dimension() = v1.dimension()|.}*/
|
||||
|
||||
Ivector<_RT,_ALLOC> compmul(const RT& r) const;
|
||||
Ivector<_NT,_ALLOC> compmul(const NT& r) const;
|
||||
|
||||
Ivector<_RT,_ALLOC> operator-() const;
|
||||
Ivector<_NT,_ALLOC> operator-() const;
|
||||
/*{\Munopfunc Negation.}*/
|
||||
|
||||
/*{\Mtext We provide component access via |iterator| and |const_iterator|
|
||||
|
|
@ -301,43 +294,43 @@ const_iterator begin() const { return v; }
|
|||
const_iterator end() const { return v+dim; }
|
||||
|
||||
|
||||
bool operator==(const Ivector<_RT,_ALLOC>& w) const;
|
||||
bool operator!=(const Ivector<_RT,_ALLOC>& w) const
|
||||
bool operator==(const Ivector<_NT,_ALLOC>& w) const;
|
||||
bool operator!=(const Ivector<_NT,_ALLOC>& w) const
|
||||
{ return !(*this == w); }
|
||||
|
||||
static int compare(const Ivector<_RT,_ALLOC>&,
|
||||
const Ivector<_RT,_ALLOC>&);
|
||||
static int compare(const Ivector<_NT,_ALLOC>&,
|
||||
const Ivector<_NT,_ALLOC>&);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*{\Mimplementation Vectors are implemented by arrays of type
|
||||
|RT|. All operations on a vector |v| take time $O(|v.dimension()|)$,
|
||||
|NT|. All operations on a vector |v| take time $O(|v.dimension()|)$,
|
||||
except for |dimension()| and $[\ ]$ which take constant time. The space
|
||||
requirement is $O(|v.dimension()|)$. }*/
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> operator*(const RT& r, const Ivector<RT,A>& v)
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> operator*(const NT& r, const Ivector<NT,A>& v)
|
||||
/*{\Mbinopfunc Componentwise multiplication with number $r$.}*/
|
||||
{ return v.compmul(r); }
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> operator*(const Ivector<RT,A>& v, const RT& r)
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> operator*(const Ivector<NT,A>& v, const NT& r)
|
||||
/*{\Mbinopfunc Componentwise multiplication with number $r$.}*/
|
||||
{ return v.compmul(r); }
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> operator*(int r, const Ivector<RT,A>& v)
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> operator*(int r, const Ivector<NT,A>& v)
|
||||
{ return v.compmul(r); }
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> operator*(const Ivector<RT,A>& v, int r)
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> operator*(const Ivector<NT,A>& v, int r)
|
||||
{ return v.compmul(r); }
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A>& Ivector<RT,A>::
|
||||
operator+=(const Ivector<RT,A>& vec)
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A>& Ivector<NT,A>::
|
||||
operator+=(const Ivector<NT,A>& vec)
|
||||
{
|
||||
check_dimensions(vec);
|
||||
register int n = dim;
|
||||
|
|
@ -345,9 +338,9 @@ operator+=(const Ivector<RT,A>& vec)
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A>& Ivector<RT,A>::
|
||||
operator-=(const Ivector<RT,A>& vec)
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A>& Ivector<NT,A>::
|
||||
operator-=(const Ivector<NT,A>& vec)
|
||||
{
|
||||
check_dimensions(vec);
|
||||
register int n = dim;
|
||||
|
|
@ -355,64 +348,64 @@ operator-=(const Ivector<RT,A>& vec)
|
|||
return *this;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> Ivector<RT,A>::
|
||||
operator+(const Ivector<RT,A>& vec) const
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> Ivector<NT,A>::
|
||||
operator+(const Ivector<NT,A>& vec) const
|
||||
{
|
||||
check_dimensions(vec);
|
||||
register int n = dim;
|
||||
Ivector<RT,A> result(n);
|
||||
Ivector<NT,A> result(n);
|
||||
while (n--) result.v[n] = v[n]+vec.v[n];
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> Ivector<RT,A>::
|
||||
operator-(const Ivector<RT,A>& vec) const
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> Ivector<NT,A>::
|
||||
operator-(const Ivector<NT,A>& vec) const
|
||||
{
|
||||
check_dimensions(vec);
|
||||
register int n = dim;
|
||||
Ivector<RT,A> result(n);
|
||||
Ivector<NT,A> result(n);
|
||||
while (n--) result.v[n] = v[n]-vec.v[n];
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> Ivector<RT,A>::
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> Ivector<NT,A>::
|
||||
operator-() const // unary minus
|
||||
{
|
||||
register int n = dim;
|
||||
Ivector<RT,A> result(n);
|
||||
Ivector<NT,A> result(n);
|
||||
while (n--) result.v[n] = -v[n];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A> Ivector<RT,A>::
|
||||
compmul(const RT& x) const
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A> Ivector<NT,A>::
|
||||
compmul(const NT& x) const
|
||||
{
|
||||
int n = dim;
|
||||
Ivector<RT,A> result(n);
|
||||
Ivector<NT,A> result(n);
|
||||
while (n--) result.v[n] = v[n] * x;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
RT Ivector<RT,A>::
|
||||
operator*(const Ivector<RT,A>& vec) const
|
||||
template <class NT, class A>
|
||||
NT Ivector<NT,A>::
|
||||
operator*(const Ivector<NT,A>& vec) const
|
||||
{
|
||||
check_dimensions(vec);
|
||||
RT result=0;
|
||||
NT result=0;
|
||||
register int n = dim;
|
||||
while (n--) result = result+v[n]*vec.v[n];
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
bool Ivector<RT,A>::
|
||||
operator==(const Ivector<RT,A>& vec) const
|
||||
template <class NT, class A>
|
||||
bool Ivector<NT,A>::
|
||||
operator==(const Ivector<NT,A>& vec) const
|
||||
{
|
||||
if (vec.dim != dim) return false;
|
||||
int i = 0;
|
||||
|
|
@ -420,9 +413,9 @@ operator==(const Ivector<RT,A>& vec) const
|
|||
return (i==dim);
|
||||
}
|
||||
|
||||
template <class RT, class A>
|
||||
int Ivector<RT,A>::
|
||||
compare(const Ivector<RT,A>& v1, const Ivector<RT,A>& v2)
|
||||
template <class NT, class A>
|
||||
int Ivector<NT,A>::
|
||||
compare(const Ivector<NT,A>& v1, const Ivector<NT,A>& v2)
|
||||
{
|
||||
register int i;
|
||||
v1.check_dimensions(v2);
|
||||
|
|
@ -431,34 +424,45 @@ compare(const Ivector<RT,A>& v1, const Ivector<RT,A>& v2)
|
|||
return (v1[i] < v2[i]) ? -1 : 1;
|
||||
}
|
||||
|
||||
template <class _RT, class _ALLOC>
|
||||
std::ostream& operator<<(std::ostream& O, const Ivector<_RT,_ALLOC>& v)
|
||||
template <class _NT, class _ALLOC>
|
||||
std::ostream& operator<<(std::ostream& os, const Ivector<_NT,_ALLOC>& v)
|
||||
/*{\Xbinopfunc writes |\Mvar| componentwise to the output stream $O$.}*/
|
||||
{
|
||||
/* syntax: d x_0 x_1 ... x_d-1 */
|
||||
O << v.dimension() << ' ';
|
||||
for (register int i = 0; i < v.dimension(); i++) O << v[i] << ' ';
|
||||
return O;
|
||||
CGAL::print_d<_NT> prt(&os);
|
||||
if (os.iword(IO::mode)==IO::PRETTY) os << "LA::Vector(";
|
||||
prt(v.dimension());
|
||||
if (os.iword(IO::mode)==IO::PRETTY) { os << " ["; prt.reset(); }
|
||||
std::for_each(v.begin(),v.end(),prt);
|
||||
if (os.iword(IO::mode)==IO::PRETTY) os << "])";
|
||||
return os;
|
||||
}
|
||||
|
||||
template <class _RT, class _ALLOC>
|
||||
std::istream& operator>>(std::istream& in, Ivector<_RT,_ALLOC>& v)
|
||||
template <class _NT, class _ALLOC>
|
||||
std::istream& operator>>(std::istream& is, Ivector<_NT,_ALLOC>& v)
|
||||
/*{\Xbinopfunc reads |\Mvar| componentwise from the input stream $I$.}*/
|
||||
{
|
||||
/* syntax: d x_0 x_1 ... x_d-1 */
|
||||
int dim = 0;
|
||||
in >> dim;
|
||||
if (v.dimension() != dim) v = Ivector<_RT,_ALLOC>(dim);
|
||||
|
||||
int i=0; while (i < v.dimension() && in >> v[i++]);
|
||||
return in;
|
||||
int dim;
|
||||
switch (is.iword(IO::mode)) {
|
||||
case IO::ASCII :
|
||||
case IO::BINARY :
|
||||
is >> dim;
|
||||
v = Ivector<_NT,_ALLOC>(dim);
|
||||
std::copy_n(std::istream_iterator<_NT>(is),dim,v.begin());
|
||||
break;
|
||||
default:
|
||||
std::cerr<<"\nStream must be in ascii or binary mode"<<std::endl;
|
||||
break;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
template <class RT, class A>
|
||||
Ivector<RT,A>::allocator_type Ivector<RT,A>::MM;
|
||||
template <class NT, class A>
|
||||
Ivector<NT,A>::allocator_type Ivector<NT,A>::MM;
|
||||
|
||||
|
||||
LA_END_NAMESPACE
|
||||
#endif // LINALG_IVECTOR_H
|
||||
CGAL_END_NAMESPACE
|
||||
#endif // CGAL_IVECTOR_H
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,468 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release : 1.1
|
||||
// release_date : Jan 2001
|
||||
//
|
||||
// file : include/CGAL/Linear_algebraCd.C
|
||||
// package : Kernel_d
|
||||
// revision : $Revision$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Herve.Bronnimann@sophia.inria.fr
|
||||
// author(s) : seel@mpi-sb.mpg.de
|
||||
// coordinator : seel@mpi-sb.mpg.de
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef CGAL_LINEAR_ALGEBRACD_C
|
||||
#define CGAL_LINEAR_ALGEBRACD_C
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template < class FT >
|
||||
std::pair<int,int>
|
||||
Linear_algebraCd<FT>::
|
||||
transpose(std::pair<int,int> p)
|
||||
{ std::swap(p.first,p.second);
|
||||
return p;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
typename Linear_algebraCd<FT>::Matrix
|
||||
Linear_algebraCd<FT>::
|
||||
transpose(const Matrix &M)
|
||||
{
|
||||
Matrix P(transpose(M.dimension()));
|
||||
int i, j;
|
||||
for (i=0; i<P.row_dimension(); ++i)
|
||||
for (j=0; j<P.column_dimension(); ++j)
|
||||
P[i][j] = M[j][i];
|
||||
return P;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
inline // in order to facilitate the optimization with unused variables
|
||||
void
|
||||
Linear_algebraCd<FT>::
|
||||
Gaussian_elimination(const Matrix &M,
|
||||
// return parameters
|
||||
Matrix &L, Matrix &U,
|
||||
std::vector<int> &row_permutation,
|
||||
std::vector<int> &column_permutation,
|
||||
FT &det, int &rank, Vector &c)
|
||||
{
|
||||
// Method: we use Gaussian elimination with division at each step
|
||||
// We do not use the variant by Bareiss (because we are on a field)
|
||||
// We obtain L, U, q, such that LM' = U, and U is upper diagonal,
|
||||
// where M' is M whose rows and columns are permuted
|
||||
// Picked up on the way:
|
||||
// det, rank, non-trivial solution c if system is degenerate (c^t M = 0)
|
||||
// Preconditions:
|
||||
CGAL_kernel_precondition( M.row_dimension() <= M.column_dimension() );
|
||||
// Temporaries
|
||||
int i, j, k;
|
||||
int dim = M.row_dimension(), cdim = M.column_dimension();
|
||||
// All the parameters are already initialized (as in C++)
|
||||
int sign = 1;
|
||||
// First create a copy of M into U, and set L and permutations to identity
|
||||
U = M;
|
||||
L = Matrix(dim,Matrix::Identity());
|
||||
for (i=0; i<dim; ++i) row_permutation.push_back(i);
|
||||
for (i=0; i<cdim; ++i) column_permutation.push_back(i);
|
||||
// Main loop : invariant is that L * M[q] = U
|
||||
// M[q] stands for M with row i permuted with row q[i]
|
||||
//DEBUG: std::cerr << "START GAUSS ELIMINATION" << std::endl;
|
||||
det = 1;
|
||||
for (k=0; k<dim; ++k) {
|
||||
// Total pivoting, without looking for the maximum entry
|
||||
for (i=k,j=k;
|
||||
j<cdim && U[i][j] == FT(0);
|
||||
(++i==dim)? ++j,i=k : 0 ) ;
|
||||
//DEBUG: std::cerr << "before swap [k="<<k<<"] :";
|
||||
//std::cerr << " found i="<<i<<" and j="<<j<<std::endl;
|
||||
//DEBUG: std::cerr << U << std::endl;
|
||||
if (j==cdim) break;
|
||||
if (i!=k) {
|
||||
//DEBUG: std::cerr << "swap row i="<<i<<" and k="<<k<<std::endl;
|
||||
U.swap_rows(i,k); L.swap_rows(i,k);
|
||||
std::swap(row_permutation[k], row_permutation[i]);
|
||||
sign = -sign;
|
||||
}
|
||||
if (j!=k) {
|
||||
//DEBUG: std::cerr << "swap column j="<<j<<" and k="<<k<<std::endl;
|
||||
U.swap_columns(j,k);
|
||||
std::swap(column_permutation[j],column_permutation[k]);
|
||||
sign = -sign;
|
||||
}
|
||||
TRACEN("after swap: "<<U);
|
||||
FT pivot = U[k][k];
|
||||
CGAL_assertion(pivot !=0);
|
||||
det *= pivot;
|
||||
for (i=k+1; i<dim; ++i) {
|
||||
FT temp = U[i][k] / pivot;
|
||||
for (j=0; j<dim; ++j)
|
||||
L[i][j] -= L[k][j] * temp;
|
||||
U[i][k] = FT(0);
|
||||
for (j=k+1; j<cdim; ++j)
|
||||
U[i][j] -= U[k][j] * temp;
|
||||
}
|
||||
}
|
||||
TRACEN("END GAUSS ELIMINATION");
|
||||
TRACEV(L);TRACEV(U);
|
||||
// By invariant, L * M[q] = U and det(M) = det
|
||||
rank = k;
|
||||
if (rank == dim) {
|
||||
det *= sign;
|
||||
} else {
|
||||
det = FT(0);
|
||||
// A vector c such that M[q] * c == 0 is obtained by L.row(dim-1)
|
||||
c = L.row(dim-1);
|
||||
}
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
Triangular_system_solver(const Matrix &U, const Matrix& L, const Vector &b,
|
||||
int rank,
|
||||
// return parameters
|
||||
Vector &x, FT &D)
|
||||
{
|
||||
// METHOD: solve system Ux=b, returning solution (x/D)
|
||||
// back substitution of x[rdim], x[rdim-1], etc.
|
||||
// depends on "free" variables x[rdim+1], etc. x[cdim]
|
||||
CGAL_kernel_assertion( U.row_dimension() == b.dimension());
|
||||
D = FT(1);
|
||||
for (int i = rank; i < U.column_dimension(); ++i)
|
||||
if ( b[i] != FT(0) )
|
||||
{ x = L.row(i); return false; }
|
||||
|
||||
x = Vector(U.column_dimension());
|
||||
for (int i = rank-1; i>=0; --i) {
|
||||
x[i] = b[i];
|
||||
for (int j = i+1; j<rank; ++j)
|
||||
x[i] -= U[i][j] * x[j];
|
||||
x[i] /= U[i][i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
inline // in order to facilitate the optimization with unused variables
|
||||
void
|
||||
Linear_algebraCd<FT>::
|
||||
Triangular_left_inverse(const Linear_algebraCd<FT>::Matrix &U,
|
||||
// return parameters
|
||||
Linear_algebraCd<FT>::Matrix &Uinv)
|
||||
{
|
||||
int i, j, k;
|
||||
CGAL_kernel_precondition( U.dimension() == transpose(Uinv.dimension()) );
|
||||
//DEBUG: std::cerr << "system : " << U << std::endl;
|
||||
// std::fill(Uinv.begin(), Uinv.end(), FT(0));
|
||||
for (i=U.row_dimension()-1; i>=0; --i) {
|
||||
Uinv[i][i] = FT(1)/U[i][i];
|
||||
for (j=i+1; j<U.column_dimension(); ++j) {
|
||||
for (k=i; k<j; ++k)
|
||||
Uinv[i][j] -= Uinv[i][k] * U[k][j];
|
||||
Uinv[i][j] /= U[j][j];
|
||||
}
|
||||
}
|
||||
//DEBUG: std::cerr << "finally : " << Uinv << std::endl;
|
||||
// std::cerr << "sanity check : " << U*Uinv << std::endl;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
inverse(const Matrix &M, Matrix &I, FT &D, Vector &c)
|
||||
{
|
||||
Matrix L(M.dimension());
|
||||
Matrix U(M.dimension());
|
||||
Matrix Uinv(M.column_dimension(),M.row_dimension());
|
||||
int rank;
|
||||
std::vector<int> rq, cq;
|
||||
Gaussian_elimination(M, L, U, rq, cq, D, rank, c);
|
||||
if (D == FT(0)) return false; // c holds the witness
|
||||
// Otherwise, compute the inverse of U
|
||||
Triangular_left_inverse(U,Uinv);
|
||||
Uinv = Uinv * L;
|
||||
// Don't forget to permute the rows of M back
|
||||
|
||||
//DEBUG: std::cerr << "inverse before permutation : " << I << std::endl;
|
||||
for (rank=0; rank<I.column_dimension(); ++rank)
|
||||
std::copy(Uinv.row_begin(cq[rank]), Uinv.row_end(cq[rank]),
|
||||
I.row_begin(rank));
|
||||
D = FT(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
inline
|
||||
typename Linear_algebraCd<FT>::Matrix
|
||||
Linear_algebraCd<FT>::
|
||||
inverse(const Matrix &M, FT &D)
|
||||
{
|
||||
CGAL_kernel_precondition( M.row_dimension() == M.column_dimension() );
|
||||
Matrix I(M.column_dimension(),M.row_dimension());
|
||||
Vector c(M.row_dimension());
|
||||
bool result = inverse(M,I,D,c);
|
||||
CGAL_kernel_precondition( result );
|
||||
return I;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
typename Linear_algebraCd<FT>::FT
|
||||
Linear_algebraCd<FT>::
|
||||
determinant(const Matrix &M, Matrix &L, Matrix &U,
|
||||
std::vector<int> &q, Vector &c)
|
||||
{
|
||||
FT det; int rank;
|
||||
std::vector<int> cq;
|
||||
Gaussian_elimination(M, L, U, q, cq, det, rank, c);
|
||||
return det;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
inline
|
||||
typename Linear_algebraCd<FT>::FT
|
||||
Linear_algebraCd<FT>::
|
||||
determinant(const Matrix &M)
|
||||
{
|
||||
Matrix L(M.dimension());
|
||||
Matrix U(M.dimension());
|
||||
std::vector<int> q;
|
||||
Vector c(M.column_dimension());
|
||||
return determinant(M,L,U,q,c);
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
inline
|
||||
Sign
|
||||
Linear_algebraCd<FT>::
|
||||
sign_of_determinant(const Matrix &M)
|
||||
{ return CGAL_NTS sign(determinant(M)); }
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
verify_determinant(const Matrix & /*M*/,
|
||||
const FT & /*D*/,
|
||||
const Matrix & /*L*/,
|
||||
const Matrix & /*U*/,
|
||||
const std::vector<int> & /*q*/,
|
||||
const Vector & /*c*/)
|
||||
{
|
||||
// TODO: verify_determinant
|
||||
return true;
|
||||
CGAL_kernel_assertion( false );
|
||||
return false;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
linear_solver(const Matrix &M, const Vector &b,
|
||||
Vector &x, FT &D, Vector &c)
|
||||
{
|
||||
CGAL_kernel_precondition( M.row_dimension() <= M.column_dimension() );
|
||||
CGAL_kernel_precondition( b.dimension() == M.row_dimension() );
|
||||
Matrix L(M.dimension());
|
||||
Matrix U(M.dimension());
|
||||
int rank;
|
||||
std::vector<int> rq, cq;
|
||||
|
||||
TRACEV(M); TRACEV(b);
|
||||
Gaussian_elimination(M, L, U, rq, cq, D, rank, c);
|
||||
TRACEV(U); TRACEV(L);
|
||||
// Compute a solution by solving triangular system
|
||||
// Since LM=U, and x is a solution of Mx=b, then Ux=Lb
|
||||
// Temporary store the solution in c
|
||||
if ( !Triangular_system_solver(U, L, L*b, rank, c, D) )
|
||||
return false;
|
||||
|
||||
// Don't forget to permute the rows of M back
|
||||
x = Vector(M.column_dimension());
|
||||
for (rank=0; rank<U.row_dimension(); ++rank)
|
||||
x[ cq[rank] ] = c[rank];
|
||||
return true;
|
||||
}
|
||||
|
||||
#define CGAL_LA_SELFTEST
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
linear_solver(const Matrix &M, const Vector &b,
|
||||
Vector &x, FT &D, Matrix &spanning_vectors,
|
||||
Vector &c)
|
||||
{
|
||||
CGAL_kernel_precondition( M.row_dimension() <= M.column_dimension() );
|
||||
CGAL_kernel_precondition( b.dimension() == M.row_dimension() );
|
||||
Matrix L,U;
|
||||
int rank;
|
||||
std::vector<int> dummy, var;
|
||||
|
||||
TRACEV(M); TRACEV(b);
|
||||
Gaussian_elimination(M, L, U, dummy, var, D, rank, c);
|
||||
TRACEV(U); TRACEV(L);
|
||||
// Compute a solution by solving triangular system
|
||||
// Since LM=U, and x is a solution of Mx=b, then Ux=Lb
|
||||
// Temporary store the solution in c
|
||||
if ( !Triangular_system_solver(U, L, L*b, rank, c, D) )
|
||||
return false;
|
||||
|
||||
// Don't forget to permute the rows of M back:
|
||||
x = Vector(M.column_dimension());
|
||||
for (rank=0; rank<U.row_dimension(); ++rank)
|
||||
x[ var[rank] ] = c[rank];
|
||||
|
||||
#ifdef CGAL_LA_SELFTEST
|
||||
CGAL_assertion( (M*x) == b );
|
||||
#endif
|
||||
|
||||
int defect = M.column_dimension() - rank;
|
||||
spanning_vectors = Matrix(M.column_dimension(),defect);
|
||||
|
||||
if (defect > 0) {
|
||||
for(int l=0; l < defect; ++l) {
|
||||
spanning_vectors(var[rank + l],l)=FT(1);
|
||||
for(int i = rank - 1; i >= 0 ; i--) {
|
||||
FT h = - U(i,rank+l);
|
||||
for (int j= i + 1; j<rank; ++j)
|
||||
h -= U(i,j)*spanning_vectors(var[j],l);
|
||||
spanning_vectors(var[i],l)= h / U(i,i);
|
||||
}
|
||||
TRACEV(spanning_vectors.column(l));
|
||||
|
||||
#ifdef CGAL_LA_SELFTEST
|
||||
CGAL_assertion( (M*spanning_vectors.column(l)).is_zero() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
linear_solver(const Matrix &M, const Vector &b, Vector &x, FT &D)
|
||||
{ Vector c;
|
||||
return linear_solver(M, b, x, D, c);
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
is_solvable(const Matrix &M, const Vector &b)
|
||||
{ Vector x; FT D;
|
||||
return linear_solver(M, b, x, D);
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
int
|
||||
Linear_algebraCd<FT>::
|
||||
homogeneous_linear_solver(const Matrix &M, Matrix &spanning_vectors)
|
||||
{
|
||||
Matrix L,U; Vector c, b(M.row_dimension());
|
||||
std::vector<int> dummy,var;
|
||||
FT D; int rank;
|
||||
Gaussian_elimination(M, L, U, dummy, var, D, rank, c);
|
||||
|
||||
#ifdef CGAL_LA_SELFTEST
|
||||
Vector x;
|
||||
Triangular_system_solver(U, L, b, rank, c, D);
|
||||
TRACEV(M);TRACEV(U);TRACEV(b);TRACEV(rank);TRACEV(c);TRACEV(D);
|
||||
x = Vector(M.column_dimension());
|
||||
for (int i=0; i<U.row_dimension(); ++i)
|
||||
x[ var[i] ] = c[i];
|
||||
CGAL_assertion( (M*x).is_zero() );
|
||||
#endif
|
||||
|
||||
int defect = M.column_dimension() - rank;
|
||||
spanning_vectors = Matrix(M.column_dimension(),defect);
|
||||
|
||||
if (defect > 0) {
|
||||
/* In the $l$-th spanning vector, $0 \le l < |defect|$ we set
|
||||
variable |var[rank + l]| to $1 = |denom|/|denom|$ and then the
|
||||
dependent variables as dictated by the $|rank| + l$ - th column of
|
||||
|C|.*/
|
||||
|
||||
for(int l=0; l < defect; ++l) {
|
||||
spanning_vectors(var[rank + l],l)=FT(1);
|
||||
for(int i = rank - 1; i >= 0 ; i--) {
|
||||
FT h = - U(i,rank+l);
|
||||
for (int j= i + 1; j<rank; ++j)
|
||||
h -= U(i,j)*spanning_vectors(var[j],l);
|
||||
spanning_vectors(var[i],l)= h / U(i,i);
|
||||
}
|
||||
TRACEV(spanning_vectors.column(l));
|
||||
|
||||
#ifdef CGAL_LA_SELFTEST
|
||||
/* we check whether the $l$ - th spanning vector is a solution
|
||||
of the homogeneous system */
|
||||
if ( !(M*spanning_vectors.column(l)).is_zero() )
|
||||
std::cerr << M*spanning_vectors.column(l) << std::endl;
|
||||
CGAL_assertion( (M*spanning_vectors.column(l)).is_zero() );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return defect;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
bool
|
||||
Linear_algebraCd<FT>::
|
||||
homogeneous_linear_solver(const Matrix &M, Vector &x)
|
||||
{
|
||||
x = Vector(M.row_dimension());
|
||||
Matrix spanning_vectors;
|
||||
int defect = homogeneous_linear_solver(M,spanning_vectors);
|
||||
if (defect == 0) return false;
|
||||
|
||||
/* return first column of |spanning_vectors| */
|
||||
for (int i = 0; i < spanning_vectors.row_dimension(); i++)
|
||||
x[i] = spanning_vectors(i,0);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
template < class FT >
|
||||
int
|
||||
Linear_algebraCd<FT>::
|
||||
independent_columns(const Matrix &M, std::vector<int> &q)
|
||||
{ CGAL_kernel_precondition( M.row_dimension() <= M.column_dimension() );
|
||||
int rank;
|
||||
std::vector<int> dummy;
|
||||
Matrix Dummy1,Dummy2; Vector Dummy3; FT null(0);
|
||||
Gaussian_elimination(M, Dummy1, Dummy2, dummy, q, null, rank, Dummy3);
|
||||
return rank;
|
||||
}
|
||||
|
||||
template < class FT >
|
||||
int
|
||||
Linear_algebraCd<FT>::
|
||||
rank(const Matrix &M)
|
||||
{ std::vector<int> q;
|
||||
if ( M.row_dimension() > M.column_dimension() )
|
||||
return independent_columns(transpose(M),q);
|
||||
return independent_columns(M,q);
|
||||
}
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
#endif // CGAL_LINEAR_ALGEBRACD_C
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,77 @@
|
|||
#ifndef CGAL_VECTOR_D_H
|
||||
#define CGAL_VECTOR_D_H
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template <class pR>
|
||||
class Vector_d : public pR::Vector_d_base
|
||||
{ public:
|
||||
typedef typename pR::Vector_d_base Base;
|
||||
typedef Vector_d<pR> Self;
|
||||
typedef pR R;
|
||||
typedef typename R::RT RT;
|
||||
typedef typename R::FT FT;
|
||||
typedef typename R::LA LA;
|
||||
|
||||
Vector_d(int d=0) : Base(d) {}
|
||||
Vector_d(int d, Null_vector v) : Base(d,v) {}
|
||||
Vector_d(int a, int b, int c = 1) : Base(a,b,c) {}
|
||||
Vector_d(const RT& a, const RT& b, const RT& c = 1) :
|
||||
Base(a,b,c) {}
|
||||
Vector_d(int a, int b, int c, int d) : Base(a,b,c,d) {}
|
||||
Vector_d(const RT& a, const RT& b, const RT& c, const RT& d) :
|
||||
Base(a,b,c,d) {}
|
||||
Vector_d(typename Base::Base_vector, int d, int i) :
|
||||
Base(typename Base::Base_vector(), d,i) {}
|
||||
|
||||
template <class InputIterator>
|
||||
Vector_d (int d, InputIterator first, InputIterator last)
|
||||
: Base (d, first, last) {}
|
||||
template <class InputIterator>
|
||||
Vector_d (int d, InputIterator first, InputIterator last, const RT& D)
|
||||
: Base (d, first, last, D) {}
|
||||
Vector_d(const Self& v) : Base(v) {}
|
||||
Vector_d(const Base& v) : Base(v) {}
|
||||
|
||||
Direction_d<R> direction() const { return Base::direction(); }
|
||||
|
||||
FT operator* (const Self& w) const
|
||||
{ return Base::operator*(w); }
|
||||
Self operator+(const Self& w) const
|
||||
{ return Base::operator+(w); }
|
||||
Self operator-(const Self& w) const
|
||||
{ return Base::operator-(w); }
|
||||
Self operator-() const
|
||||
{ return Base::operator-(); }
|
||||
|
||||
template <class NT>
|
||||
Self operator/(const NT& n) const { return Base::operator/(n); }
|
||||
|
||||
Self& operator+=(const Self& w)
|
||||
{ return static_cast<Self&>(Base::operator+=(w)); }
|
||||
Self& operator-=(const Self& w)
|
||||
{ return static_cast<Self&>(Base::operator-=(w)); }
|
||||
template <class NT>
|
||||
Self& operator*=(const NT& n)
|
||||
{ return static_cast<Self&>(Base::operator*=(n)); }
|
||||
template <class NT>
|
||||
Self& operator/=(const NT& n)
|
||||
{ return static_cast<Self&>(Base::operator/=(n)); }
|
||||
|
||||
bool operator==(const Self& w) const
|
||||
{ return Base::operator==(w); }
|
||||
bool operator!=(const Self& w) const
|
||||
{ return Base::operator!=(w); }
|
||||
|
||||
};
|
||||
|
||||
template <class R> Point_d<R>
|
||||
operator+ (const Origin& o, const Vector_d<R>& v)
|
||||
{ return Point_d<R>( o + static_cast<typename Vector_d<R>::Base>(v) ); }
|
||||
|
||||
template <class NT, class R>
|
||||
Vector_d<R> operator*(const NT& n, const Vector_d<R>& v)
|
||||
{ return Vector_d<R>( n * static_cast<typename Vector_d<R>::Base>(v) ); }
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
#endif //CGAL_VECTOR_D_H
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release : 1.1
|
||||
// release_date : %-e Dec 1999
|
||||
//
|
||||
// file : include/CGAL/Cartesian/d_utils.h
|
||||
// package : Cd (1.1)
|
||||
// revision : $Revision$
|
||||
// revision_date : $Date$
|
||||
// author : Herve Brönnimann
|
||||
// coordinator : INRIA Sophia-Antipolis (Herve.Bronnimann@sophia.inria.fr)
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef CGAL_CARTESIAN_D_UTILS_H
|
||||
#define CGAL_CARTESIAN_D_UTILS_H
|
||||
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
// Small object utility for printing objects
|
||||
// with separators depending on the ostream mode
|
||||
template < class Object >
|
||||
struct print_d
|
||||
{
|
||||
char * _separator;
|
||||
std::ostream*_os;
|
||||
bool _print_sep;
|
||||
|
||||
print_d(std::ostream *os) : _os(os), _print_sep(false)
|
||||
{
|
||||
if (_os->iword(IO::mode)==IO::ASCII) _separator = " ";
|
||||
else if (_os->iword(IO::mode)==IO::BINARY) _separator = "";
|
||||
else _separator = ", ";
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
_print_sep = false;
|
||||
}
|
||||
void operator()(const Object &x) {
|
||||
if (_print_sep && _os->iword(IO::mode) != IO::BINARY)
|
||||
(*_os) << _separator;
|
||||
(*_os) << x;
|
||||
_print_sep = true;
|
||||
}
|
||||
void operator()(const int &x) {
|
||||
if (_print_sep && _os->iword(IO::mode) != IO::BINARY)
|
||||
(*_os) << _separator;
|
||||
(*_os) << x;
|
||||
_print_sep = true;
|
||||
}
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#endif // CGAL_CARTESIAN_D_UTILS_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,122 @@
|
|||
// ======================================================================
|
||||
//
|
||||
// Copyright (c) 1999 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// release : 1.1
|
||||
// release_date : Jan 2001
|
||||
//
|
||||
// file : include/CGAL/Linear_algebra_c.h
|
||||
// package : Kernel_d
|
||||
// revision : $Revision$
|
||||
// revision_date : $Date$
|
||||
// author(s) : Herve.Bronnimann@sophia.inria.fr
|
||||
// author(s) : seel@mpi-sb.mpg.de
|
||||
// coordinator : seel@mpi-sb.mpg.de
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef CGAL_LINEAR_ALGEBRACD_H
|
||||
#define CGAL_LINEAR_ALGEBRACD_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <CGAL/Kernel_d/Ivector.h>
|
||||
#include <CGAL/Kernel_d/Imatrix.h>
|
||||
#undef _DEBUG
|
||||
#define _DEBUG 13
|
||||
#include <CGAL/Kernel_d/debug.h>
|
||||
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
template < class _FT >
|
||||
class Linear_algebraCd
|
||||
{
|
||||
public:
|
||||
typedef _FT FT;
|
||||
typedef _FT RT;
|
||||
typedef Linear_algebraCd<FT> Self;
|
||||
typedef Ivector<FT> Vector;
|
||||
typedef Imatrix<FT> Matrix;
|
||||
typedef const FT* const_iterator;
|
||||
typedef FT* iterator;
|
||||
|
||||
Linear_algebraCd() {}
|
||||
|
||||
protected:
|
||||
// Major routines for Linear_algebra_d
|
||||
static
|
||||
void Gaussian_elimination(const Matrix &M,
|
||||
Matrix &L, Matrix &U,
|
||||
std::vector<int> &row_permutation,
|
||||
std::vector<int> &column_permutation,
|
||||
FT &det, int &rank, Vector &c);
|
||||
static
|
||||
bool Triangular_system_solver(const Matrix &U, const Matrix &L,
|
||||
const Vector &b, int rank, Vector &x, FT &det);
|
||||
static
|
||||
void Triangular_left_inverse(const Matrix &U,
|
||||
Matrix &Uinv);
|
||||
|
||||
public:
|
||||
static
|
||||
std::pair<int,int> transpose(std::pair<int,int> dim);
|
||||
static
|
||||
Matrix transpose(const Matrix &M);
|
||||
|
||||
static
|
||||
bool inverse(const Matrix &M, Matrix &I, FT &D, Vector &c);
|
||||
|
||||
static
|
||||
Matrix inverse(const Matrix &M, RT &D);
|
||||
|
||||
static
|
||||
FT determinant(const Matrix &M, Matrix &L, Matrix &U,
|
||||
std::vector<int> &q, Vector &c);
|
||||
static
|
||||
FT determinant(const Matrix &M);
|
||||
|
||||
static
|
||||
Sign sign_of_determinant(const Matrix &M);
|
||||
|
||||
static
|
||||
bool verify_determinant(const Matrix &M, const RT &D,
|
||||
const Matrix &L, const Matrix &U,
|
||||
const std::vector<int> &q, const Vector &c);
|
||||
static
|
||||
bool linear_solver(const Matrix &M, const Vector &b,
|
||||
Vector &x, RT &D, Matrix &spanning_vectors, Vector &c);
|
||||
static
|
||||
bool linear_solver(const Matrix &M, const Vector &b,
|
||||
Vector &x, RT &D, Vector &c);
|
||||
static
|
||||
bool linear_solver(const Matrix &M, const Vector &b,
|
||||
Vector &x, RT &D);
|
||||
static
|
||||
bool is_solvable(const Matrix &M, const Vector &b);
|
||||
|
||||
static
|
||||
bool homogeneous_linear_solver(const Matrix &M, Vector &x);
|
||||
static
|
||||
int homogeneous_linear_solver(const Matrix &M,
|
||||
Matrix &spanning_vectors);
|
||||
static
|
||||
int rank(const Matrix &M);
|
||||
|
||||
static
|
||||
int independent_columns(const Matrix& M, std::vector<int>& columns);
|
||||
|
||||
};
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#include <CGAL/Kernel_d/Linear_algebraCd.C>
|
||||
|
||||
#endif // CGAL_LINEAR_ALGEBRACD_H
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
// ============================================================================
|
||||
//
|
||||
// Copyright (c) 1997-2000 The CGAL Consortium
|
||||
//
|
||||
// This software and related documentation is part of an INTERNAL release
|
||||
// of the Computational Geometry Algorithms Library (CGAL). It is not
|
||||
// intended for general use.
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
//
|
||||
// release : $CGAL_Revision$
|
||||
// release_date : $CGAL_Date$
|
||||
//
|
||||
// file : include/CGAL/Linear_algebraHd.h
|
||||
// package : Kernel_d
|
||||
// chapter : Kernel
|
||||
//
|
||||
// source : ddgeo/Linear_algebra.lw
|
||||
// revision : $Revision$
|
||||
// revision_date : $Date$
|
||||
//
|
||||
// author(s) : Michael Seel <seel@mpi-sb.mpg.de>
|
||||
// maintainer : Michael Seel <seel@mpi-sb.mpg.de>
|
||||
// coordinator : Susan Hert <hert@mpi-sb.mpg.de>
|
||||
//
|
||||
// implementation: Higher dimensional geometry
|
||||
// ============================================================================
|
||||
//---------------------------------------------------------------------
|
||||
// file generated by notangle from Linear_algebra.lw
|
||||
// please debug or modify noweb file
|
||||
// based on LEDA architecture by S. Naeher, C. Uhrig
|
||||
// coding: K. Mehlhorn, M. Seel
|
||||
// debugging and templatization: M. Seel
|
||||
//---------------------------------------------------------------------
|
||||
#ifndef CGAL_LINEAR_ALGEBRAHD_H
|
||||
#define CGAL_LINEAR_ALGEBRAHD_H
|
||||
|
||||
#include <CGAL/Kernel_d/Ivector.h>
|
||||
#include <CGAL/Kernel_d/Imatrix.h>
|
||||
|
||||
// #define CGAL_LA_SELFTEST
|
||||
CGAL_BEGIN_NAMESPACE
|
||||
|
||||
/*{\Moptions outfile=Linear_algebra.man}*/
|
||||
/*{\Manpage {Linear_algebraHd}{RT}{Linear Algebra on RT}{LA}}*/
|
||||
|
||||
template <class _RT, class _ALLOC = CGAL_ALLOCATOR(_RT) >
|
||||
class Linear_algebraHd
|
||||
{
|
||||
/*{\Mdefinition
|
||||
The data type |\Mname| encapsulates two classes |Matrix|, |Vector|
|
||||
and many functions of basic linear algebra. It is parametrized by a
|
||||
number type |RT|. An instance of data type |Matrix| is a matrix of
|
||||
variables of type |RT|, the so called ring type. Accordingly,
|
||||
|Vector| implements vectors of variables of type |RT|. The arithmetic
|
||||
type |RT| is required to behave like integers in the mathematical
|
||||
sense. The manual pages of |Vector| and |Matrix| follow below.
|
||||
|
||||
All functions compute the exact result, i.e., there is no rounding
|
||||
error. Most functions of linear algebra are \emph{checkable}, i.e.,
|
||||
the programs can be asked for a proof that their output is
|
||||
correct. For example, if the linear system solver declares a linear
|
||||
system $A x = b$ unsolvable it also returns a vector $c$ such that
|
||||
$c^T A = 0$ and $c^T b \neq 0$. All internal correctness checks can
|
||||
be switched on by the flag [[CGAL_LA_SELFTEST]].}*/
|
||||
|
||||
public:
|
||||
|
||||
/*{\Mtypes 5.5}*/
|
||||
|
||||
typedef _RT RT;
|
||||
/*{\Mtypemember the ring type of the components.}*/
|
||||
|
||||
typedef CGAL::Ivector<_RT,_ALLOC> Vector;
|
||||
/*{\Mtypemember the vector type.}*/
|
||||
|
||||
typedef CGAL::Imatrix<_RT,_ALLOC> Matrix;
|
||||
/*{\Mtypemember the matrix type.}*/
|
||||
|
||||
typedef _ALLOC allocator_type;
|
||||
/*{\Mtypemember the allocator used for memory management. |\Mname| is
|
||||
an abbreviation for |Linear_algebraHd<RT, ALLOC = allocator<RT,LA> >|. Thus
|
||||
|allocator_type| defaults to the standard allocator offered by the STL.}*/
|
||||
|
||||
/*{\Moperations 2 1}*/
|
||||
|
||||
static Matrix transpose(const Matrix& M);
|
||||
/*{\Mstatic returns $M^T$ ($m\times n$ - matrix). }*/
|
||||
|
||||
static bool inverse(const Matrix& M, Matrix& I, RT& D, Vector& c);
|
||||
/*{\Mstatic determines whether |M| has an inverse. It also computes
|
||||
either the inverse as $(1/D) \cdot |I|$ or when no inverse
|
||||
exists, a vector $c$ such that $c^T \cdot M = 0 $. }*/
|
||||
|
||||
static Matrix inverse(const Matrix& M, RT& D)
|
||||
/*{\Mstatic returns the inverse matrix of |M|. More precisely, $1/D$
|
||||
times the matrix returned is the inverse of |M|.\\
|
||||
\precond |determinant(M) != 0|. }*/
|
||||
{
|
||||
Matrix result;
|
||||
Vector c;
|
||||
if (!inverse(M,result,D,c))
|
||||
ERROR_HANDLER(1,"Imatrix<RT,A>::inverse: matrix is singular.");
|
||||
return result;
|
||||
}
|
||||
|
||||
static RT determinant (const Matrix& M, Matrix& L, Matrix& U,
|
||||
std::vector<int>& q, Vector& c);
|
||||
/*{\Mstatic returns the determinant $D$ of |M| and sufficient information
|
||||
to verify that the value of the determinant is correct. If
|
||||
the determinant is zero then $c$ is a vector such that
|
||||
$c^T \cdot M = 0$. If the determinant is non-zero then $L$
|
||||
and $U$ are lower and upper diagonal matrices respectively
|
||||
and $q$ encodes a permutation matrix $Q$ with $Q(i,j) = 1$
|
||||
iff $i = q(j)$ such that $L \cdot M \cdot Q = U$,
|
||||
$L(0,0) = 1$, $L(i,i) = U(i - 1,i - 1)$ for all $i$,
|
||||
$1 \le i < n$, and $D = s \cdot U(n - 1,n - 1)$ where $s$ is
|
||||
the determinant of $Q$. \precond |M| is square. }*/
|
||||
|
||||
static bool verify_determinant (const Matrix& M, RT D, Matrix& L, Matrix& U,
|
||||
const std::vector<int>& q, Vector& c);
|
||||
/*{\Mstatic verifies the conditions stated above. }*/
|
||||
|
||||
static RT determinant (const Matrix& M);
|
||||
/*{\Mstatic returns the determinant of |M|.
|
||||
\precond |M| is square. }*/
|
||||
|
||||
static int sign_of_determinant (const Matrix& M);
|
||||
/*{\Mstatic returns the sign of the determinant of |M|.
|
||||
\precond |M| is square. }*/
|
||||
|
||||
static bool linear_solver(const Matrix& M, const Vector& b,
|
||||
Vector& x, RT& D,
|
||||
Matrix& spanning_vectors,
|
||||
Vector& c);
|
||||
/*{\Mstatic determines the complete solution space of the linear system
|
||||
$M\cdot x = b$. If the system is unsolvable then
|
||||
$c^T \cdot M = 0$ and $c^T \cdot b \not= 0$.
|
||||
If the system is solvable then $(1/D) x$ is a solution, and
|
||||
the columns of |spanning_vectors| are a maximal set of linearly
|
||||
independent solutions to the corresponding homogeneous system.
|
||||
\precond |M.row_dimension() = b.dimension()|. }*/
|
||||
|
||||
static bool linear_solver(const Matrix& M, const Vector& b,
|
||||
Vector& x, RT& D,
|
||||
Vector& c)
|
||||
/*{\Mstatic determines whether the linear system $M\cdot x = b$ is
|
||||
solvable. If yes, then $(1/D) x$ is a solution, if not then
|
||||
$c^T \cdot M = 0$ and $c^T \cdot b \not= 0$.
|
||||
\precond |M.row_dimension() = b.dimension()|. }*/
|
||||
{
|
||||
Matrix spanning_vectors;
|
||||
return linear_solver(M,b,x,D,spanning_vectors,c);
|
||||
}
|
||||
|
||||
static bool linear_solver(const Matrix& M, const Vector& b,
|
||||
Vector& x, RT& D)
|
||||
/*{\Mstatic as above, but without the witness $c$
|
||||
\precond |M.row_dimension() = b.dimension()|. }*/
|
||||
{
|
||||
Matrix spanning_vectors; Vector c;
|
||||
return linear_solver(M,b,x,D,spanning_vectors,c);
|
||||
}
|
||||
|
||||
static bool is_solvable(const Matrix& M, const Vector& b)
|
||||
/*{\Mstatic determines whether the system $M \cdot x = b$ is solvable \\
|
||||
\precond |M.row_dimension() = b.dimension()|. }*/
|
||||
{
|
||||
Vector x; RT D; Matrix spanning_vectors; Vector c;
|
||||
return linear_solver(M,b,x,D,spanning_vectors,c);
|
||||
}
|
||||
|
||||
static bool homogeneous_linear_solver (const Matrix& M, Vector& x);
|
||||
/*{\Mstatic determines whether the homogeneous linear system
|
||||
$M\cdot x = 0$ has a non - trivial solution. If
|
||||
yes, then $x$ is such a solution. }*/
|
||||
|
||||
static int homogeneous_linear_solver (const Matrix& M, Matrix& spanning_vecs);
|
||||
/*{\Mstatic determines the solution space of the homogeneous linear
|
||||
system $M\cdot x = 0$. It returns the dimension of the solution space.
|
||||
Moreover the columns of |spanning_vecs| span the solution space. }*/
|
||||
|
||||
static int independent_columns (const Matrix& M, std::vector<int>& columns);
|
||||
/*{\Mstatic returns the indices of a maximal subset of independent
|
||||
columns of |M|.}*/
|
||||
|
||||
static int rank (const Matrix & M);
|
||||
/*{\Mstatic returns the rank of matrix |M| }*/
|
||||
|
||||
/*{\Mimplementation The datatype |\Mname| is a wrapper class for the
|
||||
linear algebra functionality on matrices and vectors. Operations
|
||||
|determinant|, |inverse|, |linear_solver|, and |rank| take time
|
||||
$O(n^3)$, and all other operations take time $O(nm)$. These time
|
||||
bounds ignore the cost for multiprecision arithmetic operations.
|
||||
|
||||
All functions on integer matrices compute the exact result, i.e.,
|
||||
there is no rounding error. The implemenation follows a proposal of
|
||||
J. Edmonds (J. Edmonds, Systems of distinct representatives and linear
|
||||
algebra, Journal of Research of the Bureau of National Standards, (B),
|
||||
71, 241 - 245). Most functions of linear algebra are { \em checkable
|
||||
}, i.e., the programs can be asked for a proof that their output is
|
||||
correct. For example, if the linear system solver declares a linear
|
||||
system $A x = b$ unsolvable it also returns a vector $c$ such that
|
||||
$c^T A = 0$ and $c^T b \not= 0$.}*/
|
||||
|
||||
}; // Linear_algebraHd
|
||||
|
||||
|
||||
CGAL_END_NAMESPACE
|
||||
|
||||
#include <CGAL/Kernel_d/Linear_algebraHd.C>
|
||||
#endif // CGAL_LINALG_ALGEBRAHD_H
|
||||
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Linear_algebra.h>
|
||||
#include <CGAL/Linear_algebraHd.h>
|
||||
#include <CGAL/Linear_algebraCd.h>
|
||||
#include <CGAL/random_selection.h>
|
||||
#include <CGAL/test_macros.h>
|
||||
#include <CGAL/double.h>
|
||||
#define VEC_DIM 10
|
||||
#define MAT_DIM 10
|
||||
|
||||
|
|
@ -13,173 +15,356 @@ typedef leda_integer RT;
|
|||
#include <CGAL/Gmpz.h>
|
||||
typedef CGAL::Gmpz RT;
|
||||
#else
|
||||
#include <CGAL/double.h>
|
||||
typedef double RT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef CGAL::Linear_algebra<RT> LA;
|
||||
typedef LA::Matrix Matrix;
|
||||
typedef LA::Vector Vector;
|
||||
#ifdef CGAL_USE_LEDA
|
||||
#include <CGAL/leda_real.h>
|
||||
typedef leda_real FT;
|
||||
#else
|
||||
typedef double FT;
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
CGAL_TEST_START;
|
||||
{
|
||||
int vec_dim;
|
||||
if (argc == 2) vec_dim = atoi(argv[1]);
|
||||
else vec_dim = VEC_DIM;
|
||||
{
|
||||
typedef RT NT;
|
||||
typedef CGAL::Linear_algebraHd<RT> LA;
|
||||
typedef LA::Matrix Matrix;
|
||||
typedef LA::Vector Vector;
|
||||
bool IOTEST = true;
|
||||
{
|
||||
int vec_dim;
|
||||
if (argc == 2) vec_dim = atoi(argv[1]);
|
||||
else vec_dim = VEC_DIM;
|
||||
|
||||
/* some construction and access ops */
|
||||
/* some construction and access ops */
|
||||
|
||||
Vector v0(vec_dim), v1(vec_dim), v2(vec_dim);
|
||||
int F[] = { 1,2,3,4,5 };
|
||||
Vector v11(1,2), v12(1,2,3), v13(1,2,3,4), v14(F,F+5),
|
||||
v15(v13.begin(),v13.end()),
|
||||
v16(vec_dim,Vector::Initialize(),1);
|
||||
CGAL_TEST(v13==v15);
|
||||
CGAL_TEST(v0==v1);
|
||||
for (int i = 0; i < vec_dim; i++) {
|
||||
v1[i] = i;
|
||||
v2[i] = vec_dim-i;
|
||||
}
|
||||
CGAL_TEST(v0!=v1);
|
||||
Vector v3(v1);
|
||||
CGAL_TEST(v3==v1);
|
||||
|
||||
v1 += 2*v2;
|
||||
v1 -= v2;
|
||||
v1 = -v1;
|
||||
CGAL_TEST((v1*v1 == vec_dim*vec_dim*vec_dim));
|
||||
/* squared length of (v1 + v2) = v1*v1
|
||||
should be equal to dim*dim*dim */
|
||||
RT res1 = (v1*v1 - v2*v2);
|
||||
RT res2 = ((v1-v2)*(v1+v2));
|
||||
CGAL_TEST(res1==res2);
|
||||
/* we test the third binomial formula */
|
||||
|
||||
CGAL_IO_TEST(v1,v2);
|
||||
}
|
||||
|
||||
{
|
||||
int mat_dim;
|
||||
if (argc == 2) mat_dim = atoi(argv[1]);
|
||||
else mat_dim = MAT_DIM;
|
||||
|
||||
/* some construction and access ops */
|
||||
Matrix A(mat_dim,mat_dim), B(mat_dim),
|
||||
I(mat_dim,Matrix::Identity()),
|
||||
One(mat_dim,mat_dim,Matrix::Initialize(),2);
|
||||
CGAL_TEST(A==B);
|
||||
CGAL_TEST(One*I==One);
|
||||
std::vector<Vector> F(mat_dim);
|
||||
|
||||
int i,j;
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
Vector v(mat_dim);
|
||||
for (j = 0; j < mat_dim; j++) {
|
||||
A(i,j) = i;
|
||||
B(i,j) = j;
|
||||
v[j] = j;
|
||||
Vector v0(vec_dim), v1(vec_dim), v2(vec_dim);
|
||||
int F[] = { 1,2,3,4,5 };
|
||||
Vector v11(1,2), v12(1,2,3), v13(1,2,3,4), v14(F,F+5),
|
||||
v15(v13.begin(),v13.end()),
|
||||
v16(vec_dim,Vector::Initialize(),1);
|
||||
CGAL_TEST(v13==v15);
|
||||
CGAL_TEST(v0==v1);
|
||||
for (int i = 0; i < vec_dim; i++) {
|
||||
v1[i] = i;
|
||||
v2[i] = vec_dim-i;
|
||||
}
|
||||
F[i] = v;
|
||||
}
|
||||
Matrix C(F), D(A), E(F.begin(),F.end());
|
||||
CGAL_TEST(C==F && E==F);
|
||||
/* A = (0,0,0,0...)
|
||||
(1,1,1,1...)
|
||||
(2,2,2,2...)
|
||||
...
|
||||
B = (0,1,2,3...)
|
||||
(0,1,2,3...)
|
||||
(0,1,2,3...)
|
||||
...
|
||||
C = A = D = E;
|
||||
*/
|
||||
CGAL_TEST(v0!=v1);
|
||||
Vector v3(v1);
|
||||
CGAL_TEST(v3==v1);
|
||||
|
||||
CGAL_TEST(A==C);
|
||||
CGAL_TEST(A!=B);
|
||||
CGAL_TEST(A==D);
|
||||
CGAL_TEST(A.row_dimension()==mat_dim && A.column_dimension()==mat_dim);
|
||||
CGAL_TEST(A.row(1)*B.column(1)==mat_dim);
|
||||
CGAL_IO_TEST(A,C);
|
||||
v1 += 2*v2;
|
||||
v1 -= v2;
|
||||
v1 = -v1;
|
||||
CGAL_TEST((v1*v1 == vec_dim*vec_dim*vec_dim));
|
||||
/* squared length of (v1 + v2) = v1*v1
|
||||
should be equal to dim*dim*dim */
|
||||
NT res1 = (v1*v1 - v2*v2);
|
||||
NT res2 = ((v1-v2)*(v1+v2));
|
||||
CGAL_TEST(res1==res2);
|
||||
/* we test the third binomial formula */
|
||||
|
||||
/* some basic arithmetic testing */
|
||||
C += A;
|
||||
C -= 3*A;
|
||||
C = -C;
|
||||
CGAL_TEST(C==A);
|
||||
|
||||
/* row sum test: */
|
||||
Vector ones(mat_dim), row_sum_vec(mat_dim);
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
ones[i] = 1;
|
||||
row_sum_vec[i] = i*mat_dim;
|
||||
}
|
||||
CGAL_TEST(A*ones==row_sum_vec);
|
||||
|
||||
C = A+B;
|
||||
/* matrix operations + ,* and |transpose|, |rank| */
|
||||
CGAL_TEST(C==LA::transpose(C));
|
||||
C = C-B;
|
||||
CGAL_TEST(C==A);
|
||||
|
||||
C = I+A;
|
||||
CGAL_TEST(LA::rank(C)==mat_dim);
|
||||
|
||||
/* matrix operations 2* , |determinant| */
|
||||
C = 2 * I;
|
||||
C = C * 2;
|
||||
Matrix L,U;
|
||||
Vector c;
|
||||
std::vector<int> q;
|
||||
RT det = LA::determinant(C, L, U, q, c); // det must be 2^{2*mat_dim}
|
||||
CGAL_TEST(log(det)==2*mat_dim);
|
||||
CGAL_TEST(LA::verify_determinant(C, det, L, U, q, c));
|
||||
CGAL_TEST(det == LA::determinant(C));
|
||||
CGAL_TEST(sign(det) == LA::sign_of_determinant(C));
|
||||
LA::independent_columns(C,q);
|
||||
|
||||
/* a random linear solver task: */
|
||||
Vector b(mat_dim),x(mat_dim),e;
|
||||
RT denom;
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
for (j = 0; j < mat_dim; j++)
|
||||
E(i,j) = CGAL::default_random.get_int( - mat_dim,mat_dim);
|
||||
b[i] = CGAL::default_random.get_int( - mat_dim,mat_dim);
|
||||
if (IOTEST) CGAL_IO_TEST(v1,v2);
|
||||
CGAL::set_pretty_mode ( cerr );
|
||||
}
|
||||
|
||||
// linear solver
|
||||
if (LA::linear_solver(E, b, x, denom, A, e)) {
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
LA::linear_solver(E,b,x,denom,e);
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
LA::linear_solver(E,b,x,denom);
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
CGAL_TEST(LA::is_solvable(E,b));
|
||||
}
|
||||
else {
|
||||
Vector null(mat_dim);
|
||||
CGAL_TEST(LA::transpose(E)*e==null && b*e!=0);
|
||||
CGAL_TEST(!LA::is_solvable(E,b));
|
||||
{
|
||||
int mat_dim;
|
||||
if (argc == 2) mat_dim = atoi(argv[1]);
|
||||
else mat_dim = MAT_DIM;
|
||||
|
||||
/* some construction and access ops */
|
||||
Matrix A(mat_dim,mat_dim), B(mat_dim),
|
||||
I(mat_dim,Matrix::Identity()),
|
||||
One(mat_dim,mat_dim,Matrix::Initialize(),2);
|
||||
CGAL_TEST(A==B);
|
||||
CGAL_TEST(One*I==One);
|
||||
std::vector<Vector> F(mat_dim);
|
||||
|
||||
int i,j;
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
Vector v(mat_dim);
|
||||
for (j = 0; j < mat_dim; j++) {
|
||||
A(i,j) = i;
|
||||
B(i,j) = j;
|
||||
v[j] = j;
|
||||
}
|
||||
F[i] = v;
|
||||
}
|
||||
Matrix C(F), D(A), E(F.begin(),F.end());
|
||||
CGAL_TEST(C==F && E==F);
|
||||
/* A = (0,0,0,0...)
|
||||
(1,1,1,1...)
|
||||
(2,2,2,2...)
|
||||
...
|
||||
B = (0,1,2,3...)
|
||||
(0,1,2,3...)
|
||||
(0,1,2,3...)
|
||||
...
|
||||
C = A = D = E;
|
||||
*/
|
||||
|
||||
CGAL_TEST(A==C);
|
||||
CGAL_TEST(A!=B);
|
||||
CGAL_TEST(A==D);
|
||||
CGAL_TEST(A.row_dimension()==mat_dim && A.column_dimension()==mat_dim);
|
||||
CGAL_TEST(A.row(1)*B.column(1)==mat_dim);
|
||||
|
||||
/* some basic arithmetic testing */
|
||||
C = A; C += A;
|
||||
C -= 3*A;
|
||||
C = -C;
|
||||
CGAL_TEST(C==A);
|
||||
|
||||
/* row sum test: */
|
||||
Vector ones(mat_dim), row_sum_vec(mat_dim);
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
ones[i] = 1;
|
||||
row_sum_vec[i] = i*mat_dim;
|
||||
}
|
||||
CGAL_TEST(A*ones==row_sum_vec);
|
||||
|
||||
C = A+B;
|
||||
/* matrix operations + ,* and |transpose|, |rank| */
|
||||
CGAL_TEST(C==LA::transpose(C));
|
||||
C = C-B;
|
||||
CGAL_TEST(C==A);
|
||||
C = I+A;
|
||||
CGAL_TEST(LA::rank(C)==mat_dim);
|
||||
|
||||
/* matrix operations 2* , |determinant| */
|
||||
C = 2 * I;
|
||||
C = C * 2;
|
||||
Matrix L,U;
|
||||
Vector c;
|
||||
std::vector<int> q;
|
||||
NT det = LA::determinant(C, L, U, q, c); // det must be 2^{2*mat_dim}
|
||||
NT pot = 1; for (int i=0; i<mat_dim; ++i) pot *= 4;
|
||||
CGAL_TEST(det == pot);
|
||||
CGAL_TEST(LA::verify_determinant(C, det, L, U, q, c));
|
||||
CGAL_TEST(det == LA::determinant(C));
|
||||
CGAL_TEST(sign(det) == LA::sign_of_determinant(C));
|
||||
if (IOTEST) CGAL_IO_TEST(A,C);
|
||||
/* a random linear solver task: */
|
||||
Vector b(mat_dim),x(mat_dim),e;
|
||||
NT denom;
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
for (j = 0; j < mat_dim; j++)
|
||||
C(i,j) = CGAL::default_random.get_int( - mat_dim,mat_dim);
|
||||
b[i] = CGAL::default_random.get_int( - mat_dim,mat_dim);
|
||||
}
|
||||
|
||||
for (double f = 1.0; f > 0.0; f = f-=0.1) {
|
||||
Matrix E = C;
|
||||
for (int i = 0; i< mat_dim; ++i)
|
||||
for (int j = 0; j < mat_dim; ++j)
|
||||
if ( CGAL::default_random.get_double() > f ) E(i,j)=0;
|
||||
|
||||
if (LA::linear_solver(E, b, x, denom, A, e)) {
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
LA::linear_solver(E,b,x,denom,e);
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
LA::linear_solver(E,b,x,denom);
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
CGAL_TEST(LA::is_solvable(E,b));
|
||||
}
|
||||
else {
|
||||
Vector null(mat_dim);
|
||||
CGAL_TEST(LA::transpose(E)*e==null && b*e!=0);
|
||||
CGAL_TEST(!LA::is_solvable(E,b));
|
||||
}
|
||||
|
||||
Matrix SV;
|
||||
if (LA::homogeneous_linear_solver(E,x)) {
|
||||
CGAL_TEST(E*x==Vector(mat_dim));
|
||||
CGAL_TEST(LA::homogeneous_linear_solver(E,SV)==LA::rank(SV));
|
||||
}
|
||||
|
||||
// inverse
|
||||
if (LA::inverse(E,D,denom,c)) {
|
||||
CGAL_TEST(E*D==denom*Matrix(mat_dim,Matrix::Identity()));
|
||||
CGAL_TEST(D==LA::inverse(E,denom));
|
||||
} else {
|
||||
CGAL_TEST(LA::transpose(E)*c==Vector(mat_dim));
|
||||
}
|
||||
LA::independent_columns(E,q);
|
||||
}
|
||||
}
|
||||
|
||||
Matrix SV;
|
||||
if (LA::homogeneous_linear_solver(E,x)) {
|
||||
CGAL_TEST(E*x==Vector(mat_dim));
|
||||
CGAL_TEST(LA::homogeneous_linear_solver(E,SV)==LA::rank(SV));
|
||||
}
|
||||
|
||||
// inverse
|
||||
if (LA::inverse(E,D,denom,c)) {
|
||||
CGAL_TEST(E*D==denom*Matrix(mat_dim,Matrix::Identity()));
|
||||
CGAL_TEST(D==LA::inverse(E,denom));
|
||||
} else {
|
||||
CGAL_TEST(LA::transpose(E)*c==Vector(mat_dim));
|
||||
}
|
||||
}
|
||||
{
|
||||
typedef FT NT;
|
||||
typedef CGAL::Linear_algebraCd<FT> LA;
|
||||
typedef LA::Matrix Matrix;
|
||||
typedef LA::Vector Vector;
|
||||
bool IOTEST = false;
|
||||
{
|
||||
int vec_dim;
|
||||
if (argc == 2) vec_dim = atoi(argv[1]);
|
||||
else vec_dim = VEC_DIM;
|
||||
|
||||
/* some construction and access ops */
|
||||
|
||||
Vector v0(vec_dim), v1(vec_dim), v2(vec_dim);
|
||||
int F[] = { 1,2,3,4,5 };
|
||||
Vector v11(1,2), v12(1,2,3), v13(1,2,3,4), v14(F,F+5),
|
||||
v15(v13.begin(),v13.end()),
|
||||
v16(vec_dim,Vector::Initialize(),1);
|
||||
CGAL_TEST(v13==v15);
|
||||
CGAL_TEST(v0==v1);
|
||||
for (int i = 0; i < vec_dim; i++) {
|
||||
v1[i] = i;
|
||||
v2[i] = vec_dim-i;
|
||||
}
|
||||
CGAL_TEST(v0!=v1);
|
||||
Vector v3(v1);
|
||||
CGAL_TEST(v3==v1);
|
||||
|
||||
v1 += 2*v2;
|
||||
v1 -= v2;
|
||||
v1 = -v1;
|
||||
CGAL_TEST((v1*v1 == vec_dim*vec_dim*vec_dim));
|
||||
/* squared length of (v1 + v2) = v1*v1
|
||||
should be equal to dim*dim*dim */
|
||||
NT res1 = (v1*v1 - v2*v2);
|
||||
NT res2 = ((v1-v2)*(v1+v2));
|
||||
CGAL_TEST(res1==res2);
|
||||
/* we test the third binomial formula */
|
||||
|
||||
if (IOTEST) CGAL_IO_TEST(v1,v2);
|
||||
CGAL::set_pretty_mode ( cerr );
|
||||
}
|
||||
|
||||
{
|
||||
int mat_dim;
|
||||
if (argc == 2) mat_dim = atoi(argv[1]);
|
||||
else mat_dim = MAT_DIM;
|
||||
|
||||
/* some construction and access ops */
|
||||
Matrix A(mat_dim,mat_dim), B(mat_dim),
|
||||
I(mat_dim,Matrix::Identity()),
|
||||
One(mat_dim,mat_dim,Matrix::Initialize(),2);
|
||||
CGAL_TEST(A==B);
|
||||
CGAL_TEST(One*I==One);
|
||||
std::vector<Vector> F(mat_dim);
|
||||
|
||||
int i,j;
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
Vector v(mat_dim);
|
||||
for (j = 0; j < mat_dim; j++) {
|
||||
A(i,j) = i;
|
||||
B(i,j) = j;
|
||||
v[j] = j;
|
||||
}
|
||||
F[i] = v;
|
||||
}
|
||||
Matrix C(F), D(A), E(F.begin(),F.end());
|
||||
CGAL_TEST(C==F && E==F);
|
||||
/* A = (0,0,0,0...)
|
||||
(1,1,1,1...)
|
||||
(2,2,2,2...)
|
||||
...
|
||||
B = (0,1,2,3...)
|
||||
(0,1,2,3...)
|
||||
(0,1,2,3...)
|
||||
...
|
||||
C = A = D = E;
|
||||
*/
|
||||
|
||||
CGAL_TEST(A==C);
|
||||
CGAL_TEST(A!=B);
|
||||
CGAL_TEST(A==D);
|
||||
CGAL_TEST(A.row_dimension()==mat_dim && A.column_dimension()==mat_dim);
|
||||
CGAL_TEST(A.row(1)*B.column(1)==mat_dim);
|
||||
|
||||
/* some basic arithmetic testing */
|
||||
C = A; C += A;
|
||||
C -= 3*A;
|
||||
C = -C;
|
||||
CGAL_TEST(C==A);
|
||||
|
||||
/* row sum test: */
|
||||
Vector ones(mat_dim), row_sum_vec(mat_dim);
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
ones[i] = 1;
|
||||
row_sum_vec[i] = i*mat_dim;
|
||||
}
|
||||
CGAL_TEST(A*ones==row_sum_vec);
|
||||
|
||||
C = A+B;
|
||||
/* matrix operations + ,* and |transpose|, |rank| */
|
||||
CGAL_TEST(C==LA::transpose(C));
|
||||
C = C-B;
|
||||
CGAL_TEST(C==A);
|
||||
C = I+A;
|
||||
CGAL_TEST(LA::rank(C)==mat_dim);
|
||||
|
||||
/* matrix operations 2* , |determinant| */
|
||||
C = 2 * I;
|
||||
C = C * 2;
|
||||
Matrix L,U;
|
||||
Vector c;
|
||||
std::vector<int> q;
|
||||
NT det = LA::determinant(C, L, U, q, c); // det must be 2^{2*mat_dim}
|
||||
NT pot = 1; for (int i=0; i<mat_dim; ++i) pot *= 4;
|
||||
CGAL_TEST(det == pot);
|
||||
CGAL_TEST(LA::verify_determinant(C, det, L, U, q, c));
|
||||
CGAL_TEST(det == LA::determinant(C));
|
||||
CGAL_TEST(sign(det) == LA::sign_of_determinant(C));
|
||||
if (IOTEST) CGAL_IO_TEST(A,C);
|
||||
/* a random linear solver task: */
|
||||
Vector b(mat_dim),x(mat_dim),e;
|
||||
NT denom;
|
||||
for (i = 0; i < mat_dim; i++) {
|
||||
for (j = 0; j < mat_dim; j++)
|
||||
C(i,j) = CGAL::default_random.get_int( - mat_dim,mat_dim);
|
||||
b[i] = CGAL::default_random.get_int( - mat_dim,mat_dim);
|
||||
}
|
||||
|
||||
for (double f = 1.0; f > 0.0; f = f-=0.1) {
|
||||
Matrix E = C;
|
||||
for (int i = 0; i< mat_dim; ++i)
|
||||
for (int j = 0; j < mat_dim; ++j)
|
||||
if ( CGAL::default_random.get_double() > f ) E(i,j)=0;
|
||||
|
||||
if (LA::linear_solver(E, b, x, denom, A, e)) {
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
LA::linear_solver(E,b,x,denom,e);
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
LA::linear_solver(E,b,x,denom);
|
||||
CGAL_TEST(E*x == b*denom);
|
||||
CGAL_TEST(LA::is_solvable(E,b));
|
||||
}
|
||||
else {
|
||||
Vector null(mat_dim);
|
||||
CGAL_TEST(LA::transpose(E)*e==null && b*e!=0);
|
||||
CGAL_TEST(!LA::is_solvable(E,b));
|
||||
}
|
||||
|
||||
Matrix SV;
|
||||
if (LA::homogeneous_linear_solver(E,x)) {
|
||||
CGAL_TEST(E*x==Vector(mat_dim));
|
||||
CGAL_TEST(LA::homogeneous_linear_solver(E,SV)==LA::rank(SV));
|
||||
}
|
||||
|
||||
// inverse
|
||||
if (LA::inverse(E,D,denom,c)) {
|
||||
CGAL_TEST(E*D==denom*Matrix(mat_dim,Matrix::Identity()));
|
||||
CGAL_TEST(D==LA::inverse(E,denom));
|
||||
} else {
|
||||
CGAL_TEST(LA::transpose(E)*c==Vector(mat_dim));
|
||||
}
|
||||
LA::independent_columns(E,q);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
CGAL_TEST_END;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
5
|
||||
Loading…
Reference in New Issue