summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosh Andler <scislac@gmail.com>2011-02-03 04:59:17 +0000
committerJosh Andler <scislac@gmail.com>2011-02-03 04:59:17 +0000
commit531327b6c806d863e716af55489da3c85b14c857 (patch)
tree0aa925eb74e84513bd9256e0e48b6b97c63f8617 /src
parentmore missing 2geom files (diff)
downloadinkscape-531327b6c806d863e716af55489da3c85b14c857.tar.gz
inkscape-531327b6c806d863e716af55489da3c85b14c857.zip
the last 2geom files I could find missing, linking issues still exist
(bzr r10029)
Diffstat (limited to 'src')
-rw-r--r--src/2geom/numeric/symmetric-matrix-fs-operation.h107
-rw-r--r--src/2geom/numeric/symmetric-matrix-fs-trace.h433
-rw-r--r--src/2geom/numeric/symmetric-matrix-fs.h730
3 files changed, 1270 insertions, 0 deletions
diff --git a/src/2geom/numeric/symmetric-matrix-fs-operation.h b/src/2geom/numeric/symmetric-matrix-fs-operation.h
new file mode 100644
index 000000000..5222d2734
--- /dev/null
+++ b/src/2geom/numeric/symmetric-matrix-fs-operation.h
@@ -0,0 +1,107 @@
+/*
+ * SymmetricMatrix basic operation
+ *
+ * Authors:
+ * Marco Cecchetti <mrcekets at gmail.com>
+ *
+ * Copyright 2009 authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ */
+
+#ifndef _NL_SYMMETRIC_MATRIX_FS_OPERATION_H_
+#define _NL_SYMMETRIC_MATRIX_FS_OPERATION_H_
+
+
+#include <2geom/numeric/symmetric-matrix-fs.h>
+#include <2geom/numeric/symmetric-matrix-fs-trace.h>
+
+
+
+
+namespace Geom { namespace NL {
+
+template <size_t N>
+inline
+SymmetricMatrix<N> adj(const ConstBaseSymmetricMatrix<N> & S)
+{
+ THROW_NOTIMPLEMENTED();
+ return SymmetricMatrix<N>();
+}
+
+template <>
+inline
+SymmetricMatrix<2> adj(const ConstBaseSymmetricMatrix<2> & S)
+{
+ SymmetricMatrix<2> result;
+ result.get<0,0>() = S.get<1,1>();
+ result.get<1,0>() = -S.get<1,0>();
+ result.get<1,1>() = S.get<0,0>();
+ return result;
+}
+
+template <>
+inline
+SymmetricMatrix<3> adj(const ConstBaseSymmetricMatrix<3> & S)
+{
+ SymmetricMatrix<3> result;
+
+ result.get<0,0>() = S.get<1,1>() * S.get<2,2>() - S.get<1,2>() * S.get<2,1>();
+ result.get<1,0>() = S.get<0,2>() * S.get<2,1>() - S.get<0,1>() * S.get<2,2>();
+ result.get<1,1>() = S.get<0,0>() * S.get<2,2>() - S.get<0,2>() * S.get<2,0>();
+ result.get<2,0>() = S.get<0,1>() * S.get<1,2>() - S.get<0,2>() * S.get<1,1>();
+ result.get<2,1>() = S.get<0,2>() * S.get<1,0>() - S.get<0,0>() * S.get<1,2>();
+ result.get<2,2>() = S.get<0,0>() * S.get<1,1>() - S.get<0,1>() * S.get<1,0>();
+ return result;
+}
+
+template <size_t N>
+inline
+SymmetricMatrix<N> inverse(const ConstBaseSymmetricMatrix<N> & S)
+{
+ SymmetricMatrix<N> result = adj(S);
+ double d = det(S);
+ assert (d != 0);
+ result.scale (1/d);
+ return result;
+}
+
+} /* end namespace NL*/ } /* end namespace Geom*/
+
+
+#endif // _NL_SYMMETRIC_MATRIX_FS_OPERATION_H_
+
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/2geom/numeric/symmetric-matrix-fs-trace.h b/src/2geom/numeric/symmetric-matrix-fs-trace.h
new file mode 100644
index 000000000..099c834a8
--- /dev/null
+++ b/src/2geom/numeric/symmetric-matrix-fs-trace.h
@@ -0,0 +1,433 @@
+/*
+ * SymmetricMatrix trace
+ *
+ * Authors:
+ * Marco Cecchetti <mrcekets at gmail.com>
+ *
+ * Copyright 2009 authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ */
+
+
+#ifndef _NL_TRACE_H_
+#define _NL_TRACE_H_
+
+
+#include <2geom/numeric/matrix.h>
+#include <2geom/numeric/symmetric-matrix-fs.h>
+
+
+
+
+
+namespace Geom { namespace NL {
+
+
+namespace detail
+{
+
+/*
+ * helper routines
+ */
+
+inline
+int sgn_prod (int x, int y)
+{
+ if (x == 0 || y == 0) return 0;
+ if (x == y) return 1;
+ return -1;
+}
+
+inline
+bool abs_less (double x, double y)
+{
+ return (std::fabs(x) < std::fabs(y));
+}
+
+
+/*
+ * trace K-th of symmetric matrix S of order N
+ */
+template <size_t K, size_t N>
+struct trace
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<N> & S)
+ {
+ THROW_NOTIMPLEMENTED();
+ return K;
+ }
+
+};
+
+template <size_t N>
+struct trace<1,N>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<N> & S)
+ {
+ double t = 0;
+ for (size_t i = 0; i < N; ++i)
+ {
+ t += S(i,i);
+ }
+ return t;
+ }
+};
+
+template <size_t N>
+struct trace<N,N>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<N> & S)
+ {
+ Matrix M(S);
+ return det(M);
+ }
+};
+
+/*
+ * trace for symmetric matrix of order 2
+ */
+template <>
+struct trace<1,2>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<2> & S)
+ {
+ return (S.get<0,0>() + S.get<1,1>());
+ }
+};
+
+template <>
+struct trace<2,2>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<2> & S)
+ {
+ return (S.get<0,0>() * S.get<1,1>() - S.get<0,1>() * S.get<1,0>());
+ }
+};
+
+
+/*
+ * trace for symmetric matrix of order 3
+ */
+template <>
+struct trace<1,3>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<3> & S)
+ {
+ return (S.get<0,0>() + S.get<1,1>() + S.get<2,2>());
+ }
+};
+
+template <>
+struct trace<2,3>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<3> & S)
+ {
+ double a00 = S.get<1,1>() * S.get<2,2>() - S.get<1,2>() * S.get<2,1>();
+ double a11 = S.get<0,0>() * S.get<2,2>() - S.get<0,2>() * S.get<2,0>();
+ double a22 = S.get<0,0>() * S.get<1,1>() - S.get<0,1>() * S.get<1,0>();
+ return (a00 + a11 + a22);
+ }
+};
+
+template <>
+struct trace<3,3>
+{
+ static
+ double evaluate (const ConstBaseSymmetricMatrix<3> & S)
+ {
+ double d = S.get<0,0>() * S.get<1,1>() * S.get<2,2>();
+ d += (2 * S.get<1,0>() * S.get<2,0>() * S.get<2,1>());
+ d -= (S.get<0,0>() * S.get<2,1>() * S.get<2,1>());
+ d -= (S.get<1,1>() * S.get<2,0>() * S.get<2,0>());
+ d -= (S.get<2,2>() * S.get<1,0>() * S.get<1,0>());
+ return d;
+ }
+};
+
+
+/*
+ * sign of trace K-th
+ */
+template <size_t K, size_t N>
+struct trace_sgn
+{
+ static
+ int evaluate (const ConstBaseSymmetricMatrix<N> & S)
+ {
+ double d = trace<K, N>::evaluate(S);
+ return sgn(d);
+ }
+};
+
+
+/*
+ * sign of trace for symmetric matrix of order 2
+ */
+template <>
+struct trace_sgn<2,2>
+{
+ static
+ int evaluate (const ConstBaseSymmetricMatrix<2> & S)
+ {
+ double m00 = S.get<0,0>();
+ double m10 = S.get<1,0>();
+ double m11 = S.get<1,1>();
+
+ int sm00 = sgn (m00);
+ int sm10 = sgn (m10);
+ int sm11 = sgn (m11);
+
+ if (sm10 == 0)
+ {
+ return sgn_prod (sm00, sm11);
+ }
+ else
+ {
+ int sm00m11 = sgn_prod (sm00, sm11);
+ if (sm00m11 == 1)
+ {
+ int e00, e10, e11;
+ double f00 = std::frexp (m00, &e00);
+ double f10 = std::frexp (m10, &e10);
+ double f11 = std::frexp (m11, &e11);
+
+ int e0011 = e00 + e11;
+ int e1010 = e10 << 1;
+ int ed = e0011 - e1010;
+
+ if (ed > 1)
+ {
+ return 1;
+ }
+ else if (ed < -1)
+ {
+ return -1;
+ }
+ else
+ {
+ double d = std::ldexp (f00 * f11, ed) - f10 * f10;
+ //std::cout << "trace_sgn<2,2>: det = " << d << std::endl;
+ double eps = std::ldexp (1, -50);
+ if (std::fabs(d) < eps) return 0;
+ return sgn (d);
+ }
+ }
+ return -1;
+ }
+ }
+};
+
+
+/*
+ * sign of trace for symmetric matrix of order 3
+ */
+template <>
+struct trace_sgn<2,3>
+{
+ static
+ int evaluate (const ConstBaseSymmetricMatrix<3> & S)
+ {
+ double eps = std::ldexp (1, -50);
+ double t[6];
+
+ t[0] = S.get<1,1>() * S.get<2,2>();
+ t[1] = - S.get<1,2>() * S.get<2,1>();
+ t[2] = S.get<0,0>() * S.get<2,2>();
+ t[3] = - S.get<0,2>() * S.get<2,0>();
+ t[4] = S.get<0,0>() * S.get<1,1>();
+ t[5] = - S.get<0,1>() * S.get<1,0>();
+
+
+ double* maxp = std::max_element (t, t+6, abs_less);
+ int em;
+ std::frexp(*maxp, &em);
+ double d = 0;
+ for (size_t i = 0; i < 6; ++i)
+ {
+ d += t[i];
+ }
+ double r = std::fabs (std::ldexp (d, -em)); // relative error
+ //std::cout << "trace_sgn<2,3>: d = " << d << std::endl;
+ //std::cout << "trace_sgn<2,3>: r = " << r << std::endl;
+ if (r < eps) return 0;
+ if (d > 0) return 1;
+ return -1;
+ }
+};
+
+template <>
+struct trace_sgn<3,3>
+{
+ static
+ int evaluate (const ConstBaseSymmetricMatrix<3> & S)
+ {
+
+ double eps = std::ldexp (1, -48);
+ double t[5];
+
+ t[0] = S.get<0,0>() * S.get<1,1>() * S.get<2,2>();
+ t[1] = 2 * S.get<1,0>() * S.get<2,0>() * S.get<2,1>();
+ t[2] = -(S.get<0,0>() * S.get<2,1>() * S.get<2,1>());
+ t[3] = -(S.get<1,1>() * S.get<2,0>() * S.get<2,0>());
+ t[4] = -(S.get<2,2>() * S.get<1,0>() * S.get<1,0>());
+
+ double* maxp = std::max_element (t, t+5, abs_less);
+ int em;
+ std::frexp(*maxp, &em);
+ double d = 0;
+ for (size_t i = 0; i < 5; ++i)
+ {
+ d += t[i];
+ }
+ //std::cout << "trace_sgn<3,3>: d = " << d << std::endl;
+ double r = std::fabs (std::ldexp (d, -em)); // relative error
+ //std::cout << "trace_sgn<3,3>: r = " << r << std::endl;
+
+ if (r < eps) return 0;
+ if (d > 0) return 1;
+ return -1;
+ }
+}; // end struct trace_sgn<3,3>
+
+} // end namespace detail
+
+
+template <size_t K, size_t N>
+inline
+double trace (const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ return detail::trace<K, N>::evaluate(_matrix);
+}
+
+template <size_t N>
+inline
+double trace (const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ return detail::trace<1, N>::evaluate(_matrix);
+}
+
+template <size_t N>
+inline
+double det (const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ return detail::trace<N, N>::evaluate(_matrix);
+}
+
+
+template <size_t K, size_t N>
+inline
+int trace_sgn (const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ return detail::trace_sgn<K, N>::evaluate(_matrix);
+}
+
+template <size_t N>
+inline
+int trace_sgn (const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ return detail::trace_sgn<1, N>::evaluate(_matrix);
+}
+
+template <size_t N>
+inline
+int det_sgn (const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ return detail::trace_sgn<N, N>::evaluate(_matrix);
+}
+
+/*
+template <size_t N>
+inline
+size_t rank (const ConstBaseSymmetricMatrix<N> & S)
+{
+ THROW_NOTIMPLEMENTED();
+ return 0;
+}
+
+template <>
+inline
+size_t rank<2> (const ConstBaseSymmetricMatrix<2> & S)
+{
+ if (S.is_zero()) return 0;
+ double d = S.get<0,0>() * S.get<1,1>() - S.get<0,1>() * S.get<1,0>();
+ if (d != 0) return 2;
+ return 1;
+}
+
+template <>
+inline
+size_t rank<3> (const ConstBaseSymmetricMatrix<3> & S)
+{
+ if (S.is_zero()) return 0;
+
+ double a20 = S.get<0,1>() * S.get<1,2>() - S.get<0,2>() * S.get<1,1>();
+ double a21 = S.get<0,2>() * S.get<1,0>() - S.get<0,0>() * S.get<1,2>();
+ double a22 = S.get<0,0>() * S.get<1,1>() - S.get<0,1>() * S.get<1,0>();
+ double d = a20 * S.get<2,0>() + a21 * S.get<2,1>() + a22 * S.get<2,2>();
+
+ if (d != 0) return 3;
+
+ if (a20 != 0 || a21 != 0 || a22 != 0) return 2;
+
+ double a00 = S.get<1,1>() * S.get<2,2>() - S.get<1,2>() * S.get<2,1>();
+ if (a00 != 0) return 2;
+
+ double a10 = S.get<0,2>() * S.get<2,1>() - S.get<0,1>() * S.get<2,2>();
+ if (a10 != 0) return 2;
+
+ double a11 = S.get<0,0>() * S.get<2,2>() - S.get<0,2>() * S.get<2,0>();
+ if (a11 != 0) return 2;
+
+ return 1;
+}
+*/
+
+} /* end namespace NL*/ } /* end namespace Geom*/
+
+
+
+
+#endif // _NL_TRACE_H_
+
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
diff --git a/src/2geom/numeric/symmetric-matrix-fs.h b/src/2geom/numeric/symmetric-matrix-fs.h
new file mode 100644
index 000000000..c1de27afd
--- /dev/null
+++ b/src/2geom/numeric/symmetric-matrix-fs.h
@@ -0,0 +1,730 @@
+/*
+ * SymmetricMatrix, ConstSymmetricMatrixView, SymmetricMatrixView template
+ * classes implement fixed size symmetric matrix; "views" mimic the semantic
+ * of C++ references: any operation performed on a "view" is actually performed
+ * on the "viewed object"
+ *
+ * Authors:
+ * Marco Cecchetti <mrcekets at gmail.com>
+ *
+ * Copyright 2009 authors
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ */
+
+
+#ifndef _NL_SYMMETRIC_MATRIX_FS_H_
+#define _NL_SYMMETRIC_MATRIX_FS_H_
+
+
+#include <2geom/numeric/vector.h>
+#include <2geom/numeric/matrix.h>
+#include <2geom/utils.h>
+#include <2geom/exception.h>
+
+#include <boost/static_assert.hpp>
+
+#include <cassert>
+#include <utility> // for std::pair
+#include <algorithm> // for std::swap, std::copy
+#include <sstream>
+#include <string>
+
+
+
+namespace Geom { namespace NL {
+
+
+namespace detail
+{
+
+template <size_t I, size_t J, bool B = (I < J)>
+struct index
+{
+ static const size_t K = index<J, I>::K;
+};
+
+template <size_t I, size_t J>
+struct index<I, J, false>
+{
+ static const size_t K = (((I+1) * I) >> 1) + J;
+};
+
+} // end namespace detail
+
+
+
+
+template <size_t N>
+class ConstBaseSymmetricMatrix;
+
+template <size_t N>
+class BaseSymmetricMatrix;
+
+template <size_t N>
+class SymmetricMatrix;
+
+template <size_t N>
+class ConstSymmetricMatrixView;
+
+template <size_t N>
+class SymmetricMatrixView;
+
+
+
+// declaration needed for friend clause
+template <size_t N>
+bool operator== (ConstBaseSymmetricMatrix<N> const& _smatrix1,
+ ConstBaseSymmetricMatrix<N> const& _smatrix2);
+
+
+
+
+template <size_t N>
+class ConstBaseSymmetricMatrix
+{
+ public:
+ const static size_t DIM = N;
+ const static size_t DATA_SIZE = ((DIM+1) * DIM) / 2;
+
+ public:
+
+ ConstBaseSymmetricMatrix (VectorView const& _data)
+ : m_data(_data)
+ {
+ }
+
+ double operator() (size_t i, size_t j) const
+ {
+ return m_data[get_index(i,j)];
+ }
+
+ template <size_t I, size_t J>
+ double get() const
+ {
+ BOOST_STATIC_ASSERT ((I < N && J < N));
+ return m_data[detail::index<I, J>::K];
+ }
+
+
+ size_t rows() const
+ {
+ return DIM;
+ }
+
+ size_t columns() const
+ {
+ return DIM;
+ }
+
+ bool is_zero() const
+ {
+ return m_data.is_zero();
+ }
+
+ bool is_positive() const
+ {
+ return m_data.is_positive();
+ }
+
+ bool is_negative() const
+ {
+ return m_data.is_negative();
+ }
+
+ bool is_non_negative() const
+ {
+ return m_data.is_non_negative();
+ }
+
+ double min() const
+ {
+ return m_data.min();
+ }
+
+ double max() const
+ {
+ return m_data.max();
+ }
+
+ std::pair<size_t, size_t>
+ min_index() const
+ {
+ std::pair<size_t, size_t> indices(0,0);
+ double min_value = m_data[0];
+ for (size_t i = 1; i < DIM; ++i)
+ {
+ for (size_t j = 0; j <= i; ++j)
+ {
+ if (min_value > (*this)(i,j))
+ {
+ min_value = (*this)(i,j);
+ indices.first = i;
+ indices.second = j;
+ }
+ }
+ }
+ return indices;
+ }
+
+ std::pair<size_t, size_t>
+ max_index() const
+ {
+ std::pair<size_t, size_t> indices(0,0);
+ double max_value = m_data[0];
+ for (size_t i = 1; i < DIM; ++i)
+ {
+ for (size_t j = 0; j <= i; ++j)
+ {
+ if (max_value < (*this)(i,j))
+ {
+ max_value = (*this)(i,j);
+ indices.first = i;
+ indices.second = j;
+ }
+ }
+ }
+ return indices;
+ }
+
+ size_t min_on_row_index (size_t i) const
+ {
+ size_t idx = 0;
+ double min_value = (*this)(i,0);
+ for (size_t j = 1; j < DIM; ++j)
+ {
+ if (min_value > (*this)(i,j))
+ {
+ min_value = (*this)(i,j);
+ idx = j;
+ }
+ }
+ return idx;
+ }
+
+ size_t max_on_row_index (size_t i) const
+ {
+ size_t idx = 0;
+ double max_value = (*this)(i,0);
+ for (size_t j = 1; j < DIM; ++j)
+ {
+ if (max_value < (*this)(i,j))
+ {
+ max_value = (*this)(i,j);
+ idx = j;
+ }
+ }
+ return idx;
+ }
+
+ size_t min_on_column_index (size_t j) const
+ {
+ return min_on_row_index(j);
+ }
+
+ size_t max_on_column_index (size_t j) const
+ {
+ return max_on_row_index(j);
+ }
+
+ size_t min_on_diag_index () const
+ {
+ size_t idx = 0;
+ double min_value = (*this)(0,0);
+ for (size_t i = 1; i < DIM; ++i)
+ {
+ if (min_value > (*this)(i,i))
+ {
+ min_value = (*this)(i,i);
+ idx = i;
+ }
+ }
+ return idx;
+ }
+
+ size_t max_on_diag_index () const
+ {
+ size_t idx = 0;
+ double max_value = (*this)(0,0);
+ for (size_t i = 1; i < DIM; ++i)
+ {
+ if (max_value < (*this)(i,i))
+ {
+ max_value = (*this)(i,i);
+ idx = i;
+ }
+ }
+ return idx;
+ }
+
+ std::string str() const;
+
+ ConstSymmetricMatrixView<N-1> main_minor_const_view() const;
+
+ SymmetricMatrix<N> operator- () const;
+
+ Vector operator* (ConstVectorView _vector) const
+ {
+ assert (_vector.size() == DIM);
+ Vector result(DIM, 0.0);
+
+ for (size_t i = 0; i < DIM; ++i)
+ {
+ for (size_t j = 0; j < DIM; ++j)
+ {
+ result[i] += (*this)(i,j) * _vector[j];
+ }
+ }
+ return result;
+ }
+
+ protected:
+ static size_t get_index (size_t i, size_t j)
+ {
+ if (i < j) return get_index (j, i);
+ size_t k = (i+1) * i;
+ k >>= 1;
+ k += j;
+ return k;
+ }
+
+ protected:
+ ConstVectorView get_data() const
+ {
+ return m_data;
+ }
+
+ friend
+ bool operator==<N> (ConstBaseSymmetricMatrix const& _smatrix1,
+ ConstBaseSymmetricMatrix const& _smatrix2);
+
+ protected:
+ VectorView m_data;
+
+}; //end ConstBaseSymmetricMatrix
+
+
+template <size_t N>
+class BaseSymmetricMatrix : public ConstBaseSymmetricMatrix<N>
+{
+ public:
+ typedef ConstBaseSymmetricMatrix<N> base_type;
+
+
+ public:
+
+ BaseSymmetricMatrix (VectorView const& _data)
+ : base_type(_data)
+ {
+ }
+
+ using base_type::operator();
+
+ double& operator() (size_t i, size_t j)
+ {
+ return m_data[base_type::get_index(i,j)];
+ }
+
+ template <size_t I, size_t J>
+ double& get()
+ {
+ BOOST_STATIC_ASSERT ((I < N && J < N));
+ return m_data[detail::index<I, J>::K];
+ }
+
+ void set_all (double x)
+ {
+ m_data.set_all(x);
+ }
+
+ SymmetricMatrixView<N-1> main_minor_view();
+
+ BaseSymmetricMatrix& transpose() const
+ {
+ return (*this);
+ }
+
+ BaseSymmetricMatrix& translate (double c)
+ {
+ m_data.translate(c);
+ return (*this);
+ }
+
+ BaseSymmetricMatrix& scale (double c)
+ {
+ m_data.scale(c);
+ return (*this);
+ }
+
+ BaseSymmetricMatrix& operator+= (base_type const& _smatrix)
+ {
+ m_data += (static_cast<const BaseSymmetricMatrix &>(_smatrix).m_data);
+ return (*this);
+ }
+
+ BaseSymmetricMatrix& operator-= (base_type const& _smatrix)
+ {
+ m_data -= (static_cast<const BaseSymmetricMatrix &>(_smatrix).m_data);
+ return (*this);
+ }
+
+ using base_type::DIM;
+ using base_type::DATA_SIZE;
+ using base_type::m_data;
+ using base_type::operator-;
+ using base_type::operator*;
+
+}; //end BaseSymmetricMatrix
+
+
+template <size_t N>
+class SymmetricMatrix : public BaseSymmetricMatrix<N>
+{
+ public:
+ typedef BaseSymmetricMatrix<N> base_type;
+ typedef typename base_type::base_type base_base_type;
+
+ using base_type::DIM;
+ using base_type::DATA_SIZE;
+ using base_type::m_data;
+
+ public:
+ SymmetricMatrix ()
+ : base_type (VectorView(m_adata, DATA_SIZE))
+ {
+ }
+
+ explicit
+ SymmetricMatrix (ConstVectorView _data)
+ : base_type (VectorView(m_adata, DATA_SIZE))
+ {
+ assert (_data.size() == DATA_SIZE);
+ m_data = _data;
+ }
+
+ explicit
+ SymmetricMatrix (const double _data[DATA_SIZE])
+ : base_type (VectorView(m_adata, DATA_SIZE))
+ {
+ std::copy (_data, _data + DATA_SIZE, m_adata);
+ }
+
+ SymmetricMatrix (SymmetricMatrix const& _smatrix)
+ : base_type (VectorView(m_adata, DATA_SIZE))
+ {
+ m_data = _smatrix.m_data;
+ }
+
+ explicit
+ SymmetricMatrix (base_base_type const& _smatrix)
+ : base_type (VectorView(m_adata, DATA_SIZE))
+ {
+ m_data = static_cast<const ConstSymmetricMatrixView<DIM> &>(_smatrix).m_data;
+ }
+
+ explicit
+ SymmetricMatrix (ConstMatrixView const& _matrix)
+ : base_type (VectorView(m_adata, DATA_SIZE))
+ {
+ assert (_matrix.rows() == N && _matrix.columns() == N);
+ for (size_t i = 0; i < N; ++i)
+ for (size_t j = 0; j <= i ; ++j)
+ (*this)(i,j) = _matrix(i,j);
+ }
+
+ SymmetricMatrix& operator= (SymmetricMatrix const& _smatrix)
+ {
+ m_data = _smatrix.m_data;
+ return (*this);
+ }
+
+ SymmetricMatrix& operator= (base_base_type const& _smatrix)
+ {
+
+ m_data = static_cast<const ConstSymmetricMatrixView<DIM> &>(_smatrix).m_data;
+ return (*this);
+ }
+
+ SymmetricMatrix& operator= (ConstMatrixView const& _matrix)
+ {
+ assert (_matrix.rows() == N && _matrix.columns() == N);
+ for (size_t i = 0; i < N; ++i)
+ for (size_t j = 0; j <= i ; ++j)
+ (*this)(i,j) = _matrix(i,j);
+
+ return (*this);
+ }
+
+ // needed for accessing m_adata
+ friend class ConstSymmetricMatrixView<DIM>;
+ friend class SymmetricMatrixView<DIM>;
+ private:
+ double m_adata[DATA_SIZE];
+}; //end SymmetricMatrix
+
+
+template <size_t N>
+class ConstSymmetricMatrixView : public ConstBaseSymmetricMatrix<N>
+{
+ public:
+ typedef ConstBaseSymmetricMatrix<N> base_type;
+
+ using base_type::DIM;
+ using base_type::DATA_SIZE;
+ using base_type::m_data;
+
+
+ public:
+
+ explicit
+ ConstSymmetricMatrixView (ConstVectorView _data)
+ : base_type (const_vector_view_cast(_data))
+ {
+ assert (_data.size() == DATA_SIZE);
+ }
+
+ explicit
+ ConstSymmetricMatrixView (const double _data[DATA_SIZE])
+ : base_type (const_vector_view_cast (ConstVectorView (_data, DATA_SIZE)))
+ {
+ }
+
+ ConstSymmetricMatrixView (const ConstSymmetricMatrixView & _smatrix)
+ : base_type (_smatrix.m_data)
+ {
+ }
+
+ ConstSymmetricMatrixView (const base_type & _smatrix)
+ : base_type (static_cast<const ConstSymmetricMatrixView &>(_smatrix).m_data)
+ {
+ }
+
+}; //end SymmetricMatrix
+
+
+// declaration needed for friend clause
+template <size_t N>
+void swap_view(SymmetricMatrixView<N> & m1, SymmetricMatrixView<N> & m2);
+
+
+template <size_t N>
+class SymmetricMatrixView : public BaseSymmetricMatrix<N>
+{
+ public:
+ typedef BaseSymmetricMatrix<N> base_type;
+ typedef typename base_type::base_type base_base_type;
+
+ using base_type::DIM;
+ using base_type::DATA_SIZE;
+ using base_type::m_data;
+
+ public:
+
+ explicit
+ SymmetricMatrixView (VectorView _data)
+ : base_type (_data)
+ {
+ assert (_data.size() == DATA_SIZE);
+ }
+
+ explicit
+ SymmetricMatrixView (double _data[DATA_SIZE])
+ : base_type (VectorView (_data, DATA_SIZE))
+ {
+ }
+
+ SymmetricMatrixView (const SymmetricMatrixView & _smatrix)
+ : base_type (_smatrix.m_data)
+ {
+ }
+
+ SymmetricMatrixView (SymmetricMatrix<DIM> & _smatrix)
+ : base_type (VectorView (_smatrix.m_adata, DATA_SIZE))
+ {
+ }
+
+ SymmetricMatrixView& operator= (const SymmetricMatrixView & _smatrix)
+ {
+ m_data = _smatrix.m_data;
+ return (*this);
+ }
+
+ SymmetricMatrixView& operator= (const base_base_type & _smatrix)
+ {
+ m_data = static_cast<const ConstSymmetricMatrixView<DIM> &>(_smatrix).m_data;
+ return (*this);
+ }
+
+ friend
+ void swap_view<N>(SymmetricMatrixView & m1, SymmetricMatrixView & m2);
+
+}; //end SymmetricMatrix
+
+
+
+
+/*
+ * class ConstBaseSymmetricMatrix methods
+ */
+
+template <size_t N>
+inline
+std::string ConstBaseSymmetricMatrix<N>::str() const
+{
+ std::ostringstream oss;
+ oss << (*this);
+ return oss.str();
+}
+
+template <size_t N>
+inline
+ConstSymmetricMatrixView<N-1>
+ConstBaseSymmetricMatrix<N>::main_minor_const_view() const
+{
+ ConstVectorView data(m_data.get_gsl_vector()->data, DATA_SIZE - DIM);
+ ConstSymmetricMatrixView<N-1> mm(data);
+ return mm;
+}
+
+template <size_t N>
+inline
+SymmetricMatrix<N> ConstBaseSymmetricMatrix<N>::operator- () const
+{
+ SymmetricMatrix<N> result;
+ for (size_t i = 0; i < DATA_SIZE; ++i)
+ {
+ result.m_data[i] = -m_data[i];
+ }
+ return result;
+}
+
+
+/*
+ * class ConstBaseSymmetricMatrix friend free functions
+ */
+
+template <size_t N>
+inline
+bool operator== (ConstBaseSymmetricMatrix<N> const& _smatrix1,
+ ConstBaseSymmetricMatrix<N> const& _smatrix2)
+{
+ return (_smatrix1.m_data == _smatrix2.m_data);
+}
+
+/*
+ * class ConstBaseSymmetricMatrix related free functions
+ */
+
+template< size_t N, class charT >
+inline
+std::basic_ostream<charT> &
+operator<< (std::basic_ostream<charT> & os,
+ const ConstBaseSymmetricMatrix<N> & _matrix)
+{
+ os << "[[" << _matrix(0,0);
+ for (size_t j = 1; j < N; ++j)
+ {
+ os << ", " << _matrix(0,j);
+ }
+ os << "]";
+ for (size_t i = 1; i < N; ++i)
+ {
+ os << "\n [" << _matrix(i,0);
+ for (size_t j = 1; j < N; ++j)
+ {
+ os << ", " << _matrix(i,j);
+ }
+ os << "]";
+ }
+ os << "]";
+ return os;
+}
+
+
+/*
+ * class ConstBaseSymmetricMatrix specialized methods
+ */
+
+template<>
+inline
+size_t ConstBaseSymmetricMatrix<2>::get_index (size_t i, size_t j)
+{
+ return (i+j);
+}
+
+template<>
+inline
+size_t ConstBaseSymmetricMatrix<3>::get_index (size_t i, size_t j)
+{
+ size_t k = i + j;
+ if (i == 2 || j == 2) ++k;
+ return k;
+}
+
+
+/*
+ * class BaseSymmetricMatrix methods
+ */
+
+template <size_t N>
+inline
+SymmetricMatrixView<N-1> BaseSymmetricMatrix<N>::main_minor_view()
+{
+ VectorView data(m_data.get_gsl_vector()->data, DATA_SIZE - DIM);
+ SymmetricMatrixView<N-1> mm(data);
+ return mm;
+}
+
+
+/*
+ * class SymmetricMatrixView friend free functions
+ */
+
+template <size_t N>
+inline
+void swap_view(SymmetricMatrixView<N> & m1, SymmetricMatrixView<N> & m2)
+{
+ swap_view(m1.m_data, m2.m_data);
+}
+
+} /* end namespace NL*/ } /* end namespace Geom*/
+
+
+
+
+#endif // _NL_SYMMETRIC_MATRIX_FS_H_
+
+
+
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :