//
//  Copyright Toon Knapen, Karl Meerbergen
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//

#include "ublas_heev.hpp"

#include <boost/numeric/bindings/lapack/hegv.hpp>
#include <boost/numeric/bindings/traits/ublas_matrix.hpp>
#include <boost/numeric/bindings/traits/ublas_vector.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/io.hpp>

#include <iostream>

namespace ublas = boost::numeric::ublas;
namespace lapack = boost::numeric::bindings::lapack;

template <typename T, typename W, char UPLO>
int do_memory_uplo(int n, W& workspace ) {
   typedef typename boost::numeric::bindings::traits::type_traits<T>::real_type real_type ;

   typedef ublas::matrix<T, ublas::column_major>     matrix_type ;
   typedef ublas::vector<real_type>                  vector_type ;

   // Set matrix
   matrix_type a( n, n ); a.clear();
   vector_type e1( n );
   vector_type e2( n );

   fill( a );
   matrix_type a2( a );

   matrix_type b( n, n ); b.clear();
   for (int i = 0; i < n; ++i) b(i,i) = 1;

   // Compute eigen decomposition.
   lapack::hegv( 1, 'V', UPLO, a, b, e1, workspace ) ;

   if (check_residual( a2, e1, a )) return 255 ;

   lapack::hegv( 1, 'N', UPLO, a2, b, e2, workspace ) ;
   if (norm_2( e1 - e2 ) > n * norm_2( e1 ) * std::numeric_limits< real_type >::epsilon()) return 255 ;

   // Test for a matrix range
   fill( a ); a2.assign( a );

   typedef ublas::matrix_range< matrix_type > matrix_range ;

   ublas::range r(1,n-1) ;
   matrix_range a_r( a, r, r );
   ublas::vector_range< vector_type> e_r( e1, r );
   matrix_range b_r( b, r, r );

   lapack::hegv(1, 'V', UPLO,  a_r, b_r, e_r, workspace );

   matrix_range a2_r( a2, r, r );
   if (check_residual( a2_r, e_r, a_r )) return 255 ;

   return 0 ;
} // do_memory_uplo()

template <typename T, typename W>
int do_memory_type(int n, W workspace) {
   std::cout << "  upper\n" ;
   if (do_memory_uplo<T,W,'U'>(n, workspace)) return 255 ;
   std::cout << "  lower\n" ;
   if (do_memory_uplo<T,W,'L'>(n, workspace)) return 255 ;
   return 0 ;
}

template <typename T>
struct Workspace {
   typedef ublas::vector<T>                         array_type ;
   typedef lapack::detail::workspace1< array_type > type ;

   Workspace(size_t n)
   : work_( 3*n-1 )
   {}

   type operator() () {
      return type( work_ );
   }

   array_type work_ ;
};

template <typename T>
struct Workspace< std::complex<T> > {
   typedef ublas::vector<T>                                                 real_array_type ;
   typedef ublas::vector< std::complex<T> >                                 complex_array_type ;
   typedef lapack::detail::workspace2< complex_array_type,real_array_type > type ;

   Workspace(size_t n)
   : work_( 2*n-1 )
   , rwork_( 3*n-2 )
   {}

   type operator() () {
      return type( work_, rwork_ );
   }

   complex_array_type work_ ;
   real_array_type    rwork_ ;
};

template <typename T>
int do_value_type() {
   const int n = 8 ;

   std::cout << " optimal workspace\n";
   if (do_memory_type<T,lapack::optimal_workspace>( n, lapack::optimal_workspace() ) ) return 255 ;

   std::cout << " minimal workspace\n";
   if (do_memory_type<T,lapack::minimal_workspace>( n, lapack::minimal_workspace() ) ) return 255 ;

   std::cout << " workspace array\n";
   Workspace<T> work( n );
   do_memory_type<T,typename Workspace<T>::type >( n, work() );
   return 0;
} // do_value_type()

int main() {
   // Run tests for different value_types
   std::cout << "float\n" ;
   if (do_value_type<float>()) return 255;

   std::cout << "double\n" ;
   if (do_value_type<double>()) return 255;

   std::cout << "complex<float>\n" ;
   if (do_value_type< std::complex<float> >()) return 255;

   std::cout << "complex<double>\n" ;
   if (do_value_type< std::complex<double> >()) return 255;

   std::cout << "Regression test succeeded\n" ;
   return 0;
}


#ifndef PWALK_JOHN_WALKER_HPP_
#define PWALK_JOHN_WALKER_HPP_

#include <cmath>
#include <Eigen/Dense>
#include "util/math_functions.hpp"
#include "walker.hpp"

namespace pwalk {

template <typename Dtype>
class JohnWalker: public Walker<Dtype> {
public:
  JohnWalker(const Eigen::Matrix<Dtype, Eigen::Dynamic, 1>& initialization, const Eigen::Matrix<Dtype, Eigen::Dynamic, Eigen::Dynamic>& cons_A, const Eigen::Matrix<Dtype, Eigen::Dynamic, 1>& cons_b, const Dtype r) : Walker<Dtype>(initialization, cons_A, cons_b), r_(r), alpha_(1. - 1. / std::log2(2.*Dtype(cons_A.rows())/Dtype(cons_A.cols()))), beta_(Dtype(cons_A.cols())/2./Dtype(cons_A.rows())), curr_weight_(Eigen::Matrix<Dtype, Eigen::Dynamic, 1>::Ones(cons_A.rows())){}

  // getter for radius
  Dtype getRadius() {
    return r_;
  }

  void proposal(Eigen::Matrix<Dtype, Eigen::Dynamic, 1>& new_sample);

  bool acceptRejectReverse(const Eigen::Matrix<Dtype, Eigen::Dynamic, 1>& new_sample);

  bool doSample(Eigen::Matrix<Dtype, Eigen::Dynamic, 1>& new_sample, const Dtype lazy = Dtype(0.5));

  void sqrtInvHessBarrier(const Eigen::Matrix<Dtype, Eigen::Dynamic, 1>& new_sample, Eigen::Matrix<Dtype, Eigen::Dynamic, Eigen::Dynamic>& new_sqrt_inv_hess);

private:
  const Dtype r_;
  const Dtype alpha_;
  const Dtype beta_;

  Eigen::Matrix<Dtype, Eigen::Dynamic, 1> curr_weight_;
};

} // namespace pwalk

#endif // PWALK_JOHN_WALKER_HPP_


/*
 *
 * Copyright (c) Toon Knapen & Kresimir Fresl 2003
 *
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 *
 * KF acknowledges the support of the Faculty of Civil Engineering,
 * University of Zagreb, Croatia.
 *
 */

#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_GESV_HPP
#define BOOST_NUMERIC_BINDINGS_LAPACK_GESV_HPP

#include <boost/numeric/bindings/traits/type_traits.hpp>
#include <boost/numeric/bindings/traits/traits.hpp>
#include <boost/numeric/bindings/lapack/lapack.h>
#include <boost/numeric/bindings/traits/detail/array.hpp>
#include <boost/numeric/bindings/lapack/workspace.hpp>
#include <boost/numeric/bindings/lapack/ilaenv.hpp>

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
#  include <boost/static_assert.hpp>
#  include <boost/type_traits/is_same.hpp>
#endif

#include <cassert>

namespace boost { namespace numeric { namespace bindings {

  namespace lapack {

    ///////////////////////////////////////////////////////////////////
    //
    // general system of linear equations A * X = B
    //
    ///////////////////////////////////////////////////////////////////

    /*
     * gesv() computes the solution to a system of linear equations
     * A * X = B, where A is an N-by-N matrix and X and B are N-by-NRHS
     * matrices.
     *
     * The LU decomposition with partial pivoting and row interchanges
     * is used to factor A as A = P * L * U, where P is a permutation
     * matrix, L is unit lower triangular, and U is upper triangular.
     * The factored form of A is then used to solve the system of
     * equations A * X = B.
     */

    namespace detail {

      inline
      void gesv (integer_t const n, integer_t const nrhs,
                 float* a, integer_t const lda, integer_t* ipiv,
                 float* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_SGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
      }

      inline
      void gesv (integer_t const n, integer_t const nrhs,
                 double* a, integer_t const lda, integer_t* ipiv,
                 double* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_DGESV (&n, &nrhs, a, &lda, ipiv, b, &ldb, info);
      }

      inline
      void gesv (integer_t const n, integer_t const nrhs,
                 traits::complex_f* a, integer_t const lda, integer_t* ipiv,
                 traits::complex_f* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_CGESV (&n, &nrhs,
                      traits::complex_ptr (a), &lda, ipiv,
                      traits::complex_ptr (b), &ldb, info);
      }

      inline
      void gesv (integer_t const n, integer_t const nrhs,
                 traits::complex_d* a, integer_t const lda, integer_t* ipiv,
                 traits::complex_d* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_ZGESV (&n, &nrhs,
                      traits::complex_ptr (a), &lda, ipiv,
                      traits::complex_ptr (b), &ldb, info);
      }

    } //namespace detail

    template <typename MatrA, typename MatrB, typename IVec>
    int gesv (MatrA& a, IVec& ipiv, MatrB& b) {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrB>::matrix_structure,
        traits::general_t
      >::value));
#endif

      integer_t const n = traits::matrix_size1 (a);
      assert (n == traits::matrix_size2 (a));
      assert (n == traits::matrix_size1 (b));
      assert (n == traits::vector_size (ipiv));

      integer_t info;
      detail::gesv (n, traits::matrix_size2 (b),
                    traits::matrix_storage (a),
                    traits::leading_dimension (a),
                    traits::vector_storage (ipiv),
                    traits::matrix_storage (b),
                    traits::leading_dimension (b),
                    &info);
      return info;
    }

    template <typename MatrA, typename MatrB>
    int gesv (MatrA& a, MatrB& b) {
      // with 'internal' pivot vector

      // gesv() errors:
      //   if (info == 0), successful
      //   if (info < 0), the -info argument had an illegal value
      //   -- we will use -101 if allocation fails
      //   if (info > 0), U(i-1,i-1) is exactly zero
      integer_t info = -101;
      traits::detail::array<integer_t> ipiv (traits::matrix_size1 (a));
      if (ipiv.valid())
        info = gesv (a, ipiv, b);
      return info;
    }

    /*
     * getrf() computes an LU factorization of a general M-by-N matrix A
     * using partial pivoting with row interchanges. The factorization
     * has the form A = P * L * U, where P is a permutation matrix,
     * L is lower triangular with unit diagonal elements (lower
     * trapezoidal if M > N), and U is upper triangular (upper
     * trapezoidal if M < N).
     */

    namespace detail {

      inline
      void getrf (integer_t const n, integer_t const m,
                  float* a, integer_t const lda, integer_t* ipiv, integer_t* info)
      {
        LAPACK_SGETRF (&n, &m, a, &lda, ipiv, info);
      }

      inline
      void getrf (integer_t const n, integer_t const m,
                  double* a, integer_t const lda, integer_t* ipiv, integer_t* info)
      {
        LAPACK_DGETRF (&n, &m, a, &lda, ipiv, info);
      }

      inline
      void getrf (integer_t const n, integer_t const m,
                  traits::complex_f* a, integer_t const
                  lda, integer_t* ipiv, integer_t* info)
      {
        LAPACK_CGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
      }

      inline
      void getrf (integer_t const n, integer_t const m,
                  traits::complex_d* a, integer_t const lda,
                  integer_t* ipiv, integer_t* info)
      {
        LAPACK_ZGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
      }

    } //namespace detail

    template <typename MatrA, typename IVec>
    int getrf (MatrA& a, IVec& ipiv) {

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
#endif

      integer_t const n = traits::matrix_size1 (a);
      integer_t const m = traits::matrix_size2 (a);
      assert (traits::vector_size (ipiv) == (m < n ? m : n));

      integer_t info;
      detail::getrf (n, m,
                     traits::matrix_storage (a),
                     traits::leading_dimension (a),
                     traits::vector_storage (ipiv),
                     &info);
      return info;
    }

    /*
     * getrs() solves a system of linear equations A * X = B
     * or A^T * X = B with a general N-by-N matrix A using
     * the LU factorization computed by getrf().
     */

    namespace detail {

      inline
      void getrs (char const trans, integer_t const n, integer_t const nrhs,
                  float const* a, integer_t const lda, integer_t const* ipiv,
                  float* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_SGETRS (&trans, &n, &nrhs, a, &lda, ipiv, b, &ldb, info);
      }

      inline
      void getrs (char const trans, integer_t const n, integer_t const nrhs,
                  double const* a, integer_t const lda, integer_t const* ipiv,
                  double* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_DGETRS (&trans, &n, &nrhs, a, &lda, ipiv, b, &ldb, info);
      }

      inline
      void getrs (char const trans, integer_t const n, integer_t const nrhs,
                  traits::complex_f const* a, integer_t const lda,
                  integer_t const* ipiv,
                  traits::complex_f* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_CGETRS (&trans, &n, &nrhs,
                       traits::complex_ptr (a), &lda, ipiv,
                       traits::complex_ptr (b), &ldb, info);
      }

      inline
      void getrs (char const trans, integer_t const n, integer_t const nrhs,
                  traits::complex_d const* a, integer_t const lda,
                  integer_t const* ipiv,
                  traits::complex_d* b, integer_t const ldb, integer_t* info)
      {
        LAPACK_ZGETRS (&trans, &n, &nrhs,
                       traits::complex_ptr (a), &lda, ipiv,
                       traits::complex_ptr (b), &ldb, info);
      }

    } // namespace detail

    template <typename MatrA, typename MatrB, typename IVec>
    int getrs (char const trans, MatrA const& a, IVec const& ipiv, MatrB& b)
    {
      assert (trans == 'N' || trans == 'T' || trans == 'C');

#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrA>::matrix_structure,
        traits::general_t
      >::value));
      BOOST_STATIC_ASSERT((boost::is_same<
        typename traits::matrix_traits<MatrB>::matrix_structure,
        traits::general_t
      >::value));
#endif

      integer_t const n = traits::matrix_size1 (a);
      assert (n == traits::matrix_size2 (a));
      assert (n == traits::matrix_size1 (b));
      assert (n == traits::vector_size (ipiv));

      integer_t info;
      detail::getrs (trans, n, traits::matrix_size2 (b),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
                     traits::matrix_storage (a),
#else
                     traits::matrix_storage_const (a),
#endif
                     traits::leading_dimension (a),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
                     traits::vector_storage (ipiv),
#else
                     traits::vector_storage_const (ipiv),
#endif
                     traits::matrix_storage (b),
                     traits::leading_dimension (b),
                     &info);
      return info;
    }

    template <typename MatrA, typename MatrB, typename IVec>
    inline
    int getrs (MatrA const& a, IVec const& ipiv, MatrB& b) {
      char const no_transpose = 'N';
      return getrs (no_transpose, a, ipiv, b);
    }

    /*
     * getri() computes the inverse of a matrix using
     * the LU factorization computed by getrf().
     */

    namespace detail {

      inline
      void getri (integer_t const n, float* a, integer_t const lda, integer_t const* ipiv,
                  float* work, integer_t const lwork, integer_t* info)
      {
        LAPACK_SGETRI (&n, a, &lda, ipiv, work, &lwork, info);
      }

      inline
      void getri (integer_t const n, double* a, integer_t const lda, integer_t const* ipiv,
                  double* work, integer_t const lwork, integer_t* info)
      {
        LAPACK_DGETRI (&n, a, &lda, ipiv, work, &lwork, info);
      }

      inline
      void getri (integer_t const n, traits::complex_f* a, integer_t const lda,
          integer_t const* ipiv, traits::complex_f* work, integer_t const lwork,
          integer_t* info)
      {
        LAPACK_CGETRI (&n, traits::complex_ptr (a), &lda, ipiv,
            traits::complex_ptr (work), &lwork, info);
      }

      inline
      void getri (integer_t const n, traits::complex_d* a, integer_t const lda,
          integer_t const* ipiv, traits::complex_d* work, integer_t const lwork,
          integer_t* info)
      {
        LAPACK_ZGETRI (&n, traits::complex_ptr (a), &lda, ipiv,
            traits::complex_ptr (work), &lwork, info);
      }

      template <typename MatrA, typename IVec, typename Work>
      int getri (MatrA& a, IVec const& ipiv, Work& work)
      {
        #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
        BOOST_STATIC_ASSERT((boost::is_same<
              typename traits::matrix_traits<MatrA>::matrix_structure,
              traits::general_t
              >::value));
        #endif

        integer_t const n = traits::matrix_size1 (a);
        assert (n > 0);
        assert (n <= traits::leading_dimension (a));
        assert (n == traits::matrix_size2 (a));
        assert (n == traits::vector_size (ipiv));
        assert (n <= traits::vector_size (work)); //Minimal workspace size

        integer_t info;
        //double* dummy = traits::matrix_storage (a);
        detail::getri (n, traits::matrix_storage (a),
            traits::leading_dimension (a),
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
            traits::vector_storage (ipiv),
#else
            traits::vector_storage_const (ipiv),
#endif
            traits::vector_storage (work),
            traits::vector_size (work),
            &info);
        return info;
      }

      inline
      integer_t getri_block(float)
      {
        return lapack::ilaenv(1, "sgetri", "");
      }

      inline
      integer_t getri_block(double)
      {
        return lapack::ilaenv(1, "dgetri", "");
      }

      inline
      integer_t getri_block(traits::complex_f)
      {
        return lapack::ilaenv(1, "cgetri", "");
      }

      inline
      integer_t getri_block(traits::complex_d)
      {
        return lapack::ilaenv(1, "zgetri", "");
      }

    } // namespace detail

    template <typename MatrA, typename IVec>
    int getri(MatrA& a, IVec& ipiv, minimal_workspace)
    {
      typedef typename MatrA::value_type value_type;

      std::ptrdiff_t n = traits::matrix_size1(a);
      traits::detail::array<value_type> work(std::max<std::ptrdiff_t>(1,n));

      return detail::getri(a, ipiv, work);

    }

    // optimal workspace allocation
    template <typename MatrA, typename IVec>
    int getri(MatrA& a, IVec& ipiv, optimal_workspace)
    {
      typedef typename MatrA::value_type value_type;

      std::ptrdiff_t n = traits::matrix_size1(a);
      std::ptrdiff_t nb = detail::getri_block(value_type());
      traits::detail::array<value_type> work(std::max<std::ptrdiff_t>(1,n*nb));

      return detail::getri(a, ipiv, work);
    }

    template <typename MatrA, typename IVec>
    inline
    int getri(MatrA& a, IVec& ipiv)
    {
      return getri(a, ipiv, optimal_workspace());
    }

    template <typename MatrA, typename IVec, typename Work>
    inline
    int getri(MatrA& a, IVec& ipiv, Work& work)
    {
      return detail::getri(a, ipiv, work);
    }

  } // namespace lapack

}}} // namespace boost::numeric::bindings

#endif


#include <boost/test/unit_test.hpp>

#include "Werk/Math/DiscreteDistribution.hpp"

BOOST_AUTO_TEST_SUITE(DiscreteDistributionTest)

BOOST_AUTO_TEST_CASE(TestEmpty)
{
	Werk::DiscreteDistribution<double> d;
	BOOST_REQUIRE_EQUAL(d.sampleCount(), 0);
	BOOST_REQUIRE_EQUAL(d.weightCount(), 0);
	BOOST_REQUIRE_EQUAL(d.weightSum(), 0.0);
}

BOOST_AUTO_TEST_CASE(TestBasic)
{
	Werk::DiscreteDistribution<double> d;
	d.sample(1.0, 1.0);
	d.sample(2.0, 0.5);
	d.sample(3.0, 1.0);
	BOOST_REQUIRE_EQUAL(d.sampleCount(), 3);
	BOOST_REQUIRE_EQUAL(d.weightCount(), 3);
	BOOST_REQUIRE_EQUAL(d.weightSum(), 2.5);

	d.sample(2.0, 1.5);
	BOOST_REQUIRE_EQUAL(d.sampleCount(), 4);
	BOOST_REQUIRE_EQUAL(d.weightCount(), 3);
	BOOST_REQUIRE_EQUAL(d.weightSum(), 4.0);

	BOOST_REQUIRE_EQUAL(d.pdf(1.0), 0.25);
	BOOST_REQUIRE_EQUAL(d.pdf(2.0), 0.5);
	BOOST_REQUIRE_EQUAL(d.pdf(3.0), 0.25);

	BOOST_REQUIRE_EQUAL(d.cdf(1.0), 0.25);
	BOOST_REQUIRE_EQUAL(d.cdf(2.0), 0.75);
	BOOST_REQUIRE_EQUAL(d.cdf(2.9), 0.75);
	BOOST_REQUIRE_EQUAL(d.cdf(3.0), 1.0);
	BOOST_REQUIRE_EQUAL(d.cdf(4.0), 1.0);
}

BOOST_AUTO_TEST_SUITE_END()


#define BOOST_DISABLE_ASSERTS
#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/push_relabel_max_flow.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include "MaxFlowDouble.hpp"
using namespace std;
using namespace boost;

Network::Network(): g(), rev(get(edge_reverse, g)), capacity(get(edge_capacity, g)), residual_capacity(get(edge_residual_capacity, g)) {}

Network::Vertex Network::AddVertex() {
  return add_vertex(g);
}

Network::Edge Network::AddEdge(Vertex &v1, Vertex &v2, const double capacity) {
  Traits::edge_descriptor e1 = add_edge(v1, v2, g).first;
  Traits::edge_descriptor e2 = add_edge(v2, v1, g).first;
  put(edge_capacity, g, e1, capacity);
  rev[e1] = e2;
  rev[e2] = e1;
  return e1;
}

double Network::MaxFlow(Vertex &s, Vertex &t) {
  return push_relabel_max_flow(g, s, t); // Boost library also provides boykov_kolmogorov_max_flow (needs "#include <boost/graph/boykov_kolmogorov_max_flow.hpp>")
}

struct Network::NonSaturatedEdges {
  NonSaturatedEdges() {}
  NonSaturatedEdges(property_map<Graph, edge_residual_capacity_t>::type residual_capacity):
    residual_capacity(residual_capacity) {}
  property_map<Graph, edge_residual_capacity_t>::type residual_capacity;
  bool operator ()(const Edge &e) const {
    return residual_capacity[e] > 1e-9;
  }
};

void Network::BfsOnResidualGraph(Vertex &s) {
  NonSaturatedEdges filter(get(edge_residual_capacity, g));
  filtered_graph<Graph, NonSaturatedEdges> fg(g, filter);
  color = get(vertex_color, g);
  boost::queue<Vertex> Q;
  default_bfs_visitor vis;
  breadth_first_search(fg, s, Q, vis, color);
}


/* Copyright 2022 Zuru Tech HK Limited.
 *
 * Licensed under the Apache License, Version 2.0(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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SOLVERS_CUSPARSESOLVER_HPP
#define SOLVERS_CUSPARSESOLVER_HPP

#include <Eigen/Dense>

#include <solvers/Solver.hpp>
#include <solvers/SparseSystem.hpp>

namespace solvers {

enum class CuSparseMethod { QR, Cholesky };
enum class CuSparseReorder { None, SymRCM, SymAMD, METIS };

/**
 * \brief CuSparseSolver Direct solver based on cuSPARSE library.
 */
class CuSparseSolver : public Solver {
private:
    /**
     * \brief _method Resolution algorithm.
     */
    CuSparseMethod _method;

    /**
     * \brief _reorder Algorithm of node reordering used to reduce fill-in.
     */
    CuSparseReorder _reorder;

public:
    explicit CuSparseSolver(
        const CuSparseMethod method = CuSparseMethod::Cholesky,
        const CuSparseReorder reorder = CuSparseReorder::METIS)
        : _method(method), _reorder(reorder){};

    Eigen::VectorXd solve(const SparseSystem& system,
                          double& duration) const override;
};

}    // namespace solvers

#endif    // SOLVERS_CUSPARSESOLVER_HPP


/**
 * @file
 * @brief Implementation of the make_QuadRuleNodal.
 * @author Raffael Casagrande
 * @date   2018-12-26 10:25:52
 * @copyright MIT License
 */

#include "make_quad_rule_nodal.h"
#include <boost/core/ref.hpp>

namespace lf::quad {
QuadRule make_QuadRuleNodal(base::RefEl ref_el) {
  double ref_el_vol = 1.0;
  if (ref_el == base::RefEl::kTria()) {
    ref_el_vol = 0.5;
  }
  return QuadRule(ref_el, ref_el.NodeCoords(),
                  Eigen::VectorXd::Constant(ref_el.NumNodes(),
                                            ref_el_vol / ref_el.NumNodes()),
                  1);
}
}  // namespace lf::quad


//  Copyright (c) 2021 DNV AS
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt

#include <jsScript/jsMath.h>
#include <jsScript/jsClass.h>
#include <jsScript/jsUnitValue.h>
#include <jsScript/jsQuantity.h>
#include <limits>
#include <stdlib.h>
#include <time.h>
#include <cmath>
#include "Units/Angle.h"
#include "Units/Runtime/DynamicQuantity.h"
#include "Units/Math.h"
#include "Reflection/Classes/Class.h"
#include "Reflection/Attributes/ExampleAttribute.h"
#include <Reflection/Containers/ReflectVector.h>
#include "Reflection/Members/GlobalType.h"
#include "jsMathImpl.h"

/*#include <boost/math/special_functions/acosh.hpp>
#include <boost/math/special_functions/asinh.hpp>
#include <boost/math/special_functions/atanh.hpp>*/
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace DNVS::MoFa::Units;
using namespace DNVS::MoFa::Units::Runtime;
using namespace DNVS::MoFa::Reflection::Classes;
using namespace std;

void jsMath::init(jsTypeLibrary& typeLibrary)
{
    srand((unsigned)time(NULL));

    using namespace DNVS::MoFa::Reflection::Classes;
    Class<jsMath> cls(typeLibrary.GetReflectionTypeLibrary(), "Math");
    cls.AddDocumentation("The Math object - methods");

    cls.StaticFunction("timer", [](long t0) { return long(time(nullptr) - t0); })
        .AddDocumentation("for performance test, returns the lapsed time in seconds since t0")
        .AddSignature("t0")
        .AddAttribute<ExampleAttribute>(
            "Math.timer(0); //Returns time in seconds since 1. January 1970\n"
            "t0 = Math.timer(0);  //Initialises the variable a\n"
            "t  = Math.timer(t0); //Computes time difference in seconds since when variable t0 was set\n"
            "print(t);            //Writes lapsed time to the journal file window\n");

    cls.StaticGet("E", 2.7182818284590452354)
        .AddDocumentation("The number value for e, the base of the natural logarithms, which is approximately 2.7182818284590452354")
        .AddAttribute<ExampleAttribute>(
            "Math.ln(E); //Returns 1"
            "Math.pow(E,5); //The same as Math.exp(5)");
    cls.StaticGet("LN10", 2.302585092994046).AddDocumentation("The number value for the natural logarithm of 10, which is approximately 2.302585092994046");
    cls.StaticGet("LN2", 0.6931471805599453).AddDocumentation("The number value for the natural logarithm of 2, which is approximately 0.6931471805599453");
    cls.StaticGet("LOG2E", 1.4426950408889634).AddDocumentation("The number value for the base-2 logarithm of e, the base of the natural logarithms; this value is approximately 1.4426950408889634");
    cls.StaticGet("LOG10E", 0.4342944819032518).AddDocumentation("The number value for the base-10 logarithm of e, the base of the natural logarithms; this value is approximately 0.4342944819032518");
    cls.StaticGet("PI", 3.1415926535897932).AddDocumentation("The number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932");
    cls.StaticGet("SQRT1_2", 0.7071067811865476).AddDocumentation("The number value for the square root of 1/2, which is approximately 0.7071067811865476");
    cls.StaticGet("SQRT2", 1.4142135623730951).AddDocumentation("The number value for the square root of 2, which is approximately 1.4142135623730951");

    Class<DNVS::MoFa::Reflection::Members::GlobalType>(typeLibrary.GetReflectionTypeLibrary(), "")
        .StaticGet("Math", jsMath());
    InitFunctionsForDouble<double>(cls);
    InitFunctionsForUnits<DynamicQuantity>(cls);

}


/*
 * BSD 2-Clause License
 *
 * Copyright (c) 2012-2019, CNRS-UM LIRMM, CNRS-AIST JRL
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

// gtest
#include <gtest/gtest.h>

// Eigen
#include <Eigen/Dense>

// EigenQP
#include "eigen-qld/QLD.h"

struct QP1 {
  QP1() {
    nrvar = 6;
    nreq = 3;
    nrineq = 2;

    Q.resize(nrvar, nrvar);
    Aeq.resize(nreq, nrvar);
    Aineq.resize(nrineq, nrvar);
    A.resize(nreq + nrineq, nrvar);

    C.resize(nrvar);
    Beq.resize(nreq);
    Bineq.resize(nrineq);
    B.resize(nreq + nrineq);
    XL.resize(nrvar);
    XU.resize(nrvar);
    X.resize(nrvar);

    Aeq << 1., -1., 1., 0., 3., 1., -1., 0., -3., -4., 5., 6., 2., 5., 3., 0., 1., 0.;
    Beq << 1., 2., 3.;

    Aineq << 0., 1., 0., 1., 2., -1., -1., 0., 2., 1., 1., 0.;
    Bineq << -1., 2.5;

    A.topRows(nreq) = Aeq;
    A.bottomRows(nrineq) = -Aineq;

    B.head(nreq) = -Beq;
    B.tail(nrineq) = Bineq;

    // with  x between ci and cs:
    XL << -1000., -10000., 0., -1000., -1000., -1000.;
    XU << 10000., 100., 1.5, 100., 100., 1000.;

    // and minimize 0.5*x'*Q*x + p'*x with
    C << 1., 2., 3., 4., 5., 6.;
    Q.setIdentity();

    X << 1.7975426, -0.3381487, 0.1633880, -4.9884023, 0.6054943, -3.1155623;
  }

  int nrvar, nreq, nrineq;
  Eigen::MatrixXd Q, Aeq, Aineq, A;
  Eigen::VectorXd C, Beq, Bineq, B, XL, XU, X;
};

void ineqWithXBounds(Eigen::MatrixXd& Aineq, Eigen::VectorXd& Bineq, const Eigen::VectorXd& XL, const Eigen::VectorXd& XU) {
  double inf = std::numeric_limits<double>::infinity();

  std::vector<std::pair<int, double>> lbounds, ubounds;

  for (int i = 0; i < XL.rows(); ++i) {
    if (XL[i] != -inf) lbounds.emplace_back(i, XL[i]);
    if (XU[i] != inf) ubounds.emplace_back(i, XU[i]);
  }

  long int nrconstr = Bineq.rows() + static_cast<long int>(lbounds.size()) + static_cast<long int>(ubounds.size());

  Eigen::MatrixXd A(Eigen::MatrixXd::Zero(nrconstr, Aineq.cols()));
  Eigen::VectorXd B(Eigen::VectorXd::Zero(nrconstr));

  A.block(0, 0, Aineq.rows(), Aineq.cols()) = Aineq;
  B.segment(0, Bineq.rows()) = Bineq;

  int start = static_cast<int>(Aineq.rows());

  for (int i = 0; i < static_cast<int>(lbounds.size()); ++i) {
    const auto& b = lbounds[i];
    A(start, b.first) = -1.;
    B(start) = -b.second;
    ++start;
  }

  for (int i = 0; i < static_cast<int>(ubounds.size()); ++i) {
    const auto& b = ubounds[i];
    A(start, b.first) = 1.;
    B(start) = b.second;
    ++start;
  }

  Aineq = A;
  Bineq = B;
}

TEST(QPTest, QLD) {  // NOLINT
  QP1 qp1;
  Eigen::QLD qld(qp1.nrvar, qp1.nreq, qp1.nrineq);
  qld.solve(qp1.Q, qp1.C, qp1.Aeq, qp1.Beq, qp1.Aineq, qp1.Bineq, qp1.XL, qp1.XU);
  ASSERT_NEAR((qld.result() - qp1.X).norm(), 0., 1e-6);
  Eigen::QLDDirect qldd(qp1.nrvar, qp1.nreq, qp1.nrineq);
  qldd.solve(qp1.Q, qp1.C, qp1.A, qp1.B, qp1.XL, qp1.XU, 3);
  ASSERT_NEAR((qld.result() - qp1.X).norm(), 0., 1e-6);
}

TEST(QPTest, QLDSize) {  // NOLINT
  QP1 qp1;
  Eigen::QLD qld(qp1.nrvar, qp1.nreq + 10, qp1.nrineq + 22);
  qld.solve(qp1.Q, qp1.C, qp1.Aeq, qp1.Beq, qp1.Aineq, qp1.Bineq, qp1.XL, qp1.XU);
  ASSERT_NEAR((qld.result() - qp1.X).norm(), 0., 1e-6);
}

TEST(QPTest, IneqWithXBounds) {  // NOLINT
  QP1 qp1;
  ineqWithXBounds(qp1.Aineq, qp1.Bineq, qp1.XL, qp1.XU);
  double inf = std::numeric_limits<double>::infinity();
  for (int i = 0; i < qp1.nrvar; ++i) {
    qp1.XL[i] = -inf;
    qp1.XU[i] = inf;
  }
  int nrineq = static_cast<int>(qp1.Aineq.rows());
  Eigen::QLD qld(qp1.nrvar, qp1.nreq, nrineq);
  qld.solve(qp1.Q, qp1.C, qp1.Aeq, qp1.Beq, qp1.Aineq, qp1.Bineq, qp1.XL, qp1.XU);
  ASSERT_NEAR((qld.result() - qp1.X).norm(), 0., 1e-6);
}


// Copyright (C) 2015 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include <ceres/ceres.h>
#include <ceres/rotation.h>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <glog/logging.h>

#include "gtest/gtest.h"
#include "theia/math/util.h"
#include "theia/sfm/transformation/align_rotations.h"

namespace theia {

namespace {

void ApplyRotation(const Eigen::Matrix3d& rotation_transformation,
                   const double noise,
                   Eigen::Vector3d* rotation) {
  const Eigen::Matrix3d noisy_rotation =
      Eigen::AngleAxisd(DegToRad(noise), Eigen::Vector3d::Random().normalized())
          .toRotationMatrix();

  // Apply the transformation to the rotation.
  Eigen::Matrix3d rotation_mat;
  ceres::AngleAxisToRotationMatrix(
      rotation->data(), ceres::ColumnMajorAdapter3x3(rotation_mat.data()));
  const Eigen::Matrix3d transformed_rotation =
      rotation_mat * (noisy_rotation * rotation_transformation);

  // Convert back to angle axis.
  ceres::RotationMatrixToAngleAxis(
      ceres::ColumnMajorAdapter3x3(transformed_rotation.data()),
      rotation->data());
}

void TestAlignRotations(const int num_views,
                        const double noise_degrees,
                        const double tolerance) {
  std::vector<Eigen::Vector3d> gt_rotations(num_views);
  std::vector<Eigen::Vector3d> rotations(num_views);

  Eigen::Matrix3d rotation_transformation = Eigen::AngleAxisd(
      15.0, Eigen::Vector3d::Random().normalized()).toRotationMatrix();
  for (int i = 0; i < num_views; i++) {
    gt_rotations[i] = Eigen::Vector3d::Random();
    rotations[i] = gt_rotations[i];
    ApplyRotation(rotation_transformation, noise_degrees, &rotations[i]);
  }

  AlignRotations(gt_rotations, &rotations);

  for (int i = 0; i < num_views; i++) {
    EXPECT_LT((gt_rotations[i] - rotations[i]).norm(), tolerance);
  }
}

}  // namespace

TEST(AlignRotations, NoNoise) {
  static const int kNumViews = 20;
  static const double kTolerance = 1e-8;
  static const double kNoise = 0.0;
  TestAlignRotations(kNumViews, kNoise, kTolerance);
}

TEST(AlignRotations, Noise) {
  static const int kNumViews = 20;
  static const double kTolerance = 5e-2;
  static const double kNoise = 1.0;
  TestAlignRotations(kNumViews, kNoise, kTolerance);
}

}  // namespace theia


/*
 *  carpack.hpp
 *  carpack
 *
 *  Created by Dr. Brandon Kelly on 12/19/12.
 *
 *  Header file containing the class definitions and function protoypes
 *  for CARMCMC.
 *
 */

#ifndef __CARPACK_HDEF__
#define __CARPACK_HDEF__

#include <boost/math/special_functions/binomial.hpp>
#include <stdexcept>
#include <string>
#include <memory>
#include <random.hpp>
#include <proposals.hpp>
#include <samplers.hpp>
#include <steps.hpp>
#include <parameters.hpp>
#include "kfilter.hpp"

/*
 First-order continuous time autoregressive process (CAR(1)) class. Note that this is the same
 as an Ornstein-Uhlenbeck process. A CAR(1) process, Y(t), is defined as

 dY(t) = -omega * (Y(t) - mu) * dt + sigma * dW(t),

 where tau = 1 / omega is the "characteristic time scale" of the process, mu is the mean
 of the process, sigma is the amplitude of the driving noise, and the driving noise dW(t)
 is the derivative of the Weiner process (i.e., a white noise process). The variance of the
 process is Var(Y(t)) = sigma^2 / (2 * omega).

 The data member of this class include the time series values (y), the 1-sigma uncertainties
 on y (yerr), and the time values (time). Note that it is assumed that the CAR(1) process is
 Gaussian, and that the uncertainties on y are normally distributed with mean zero. The member
 functions of this class include methods to calculate the Kalman filter and the logarithms of the
 posterior probability distribution. The parameters of the CAR(1) process are held in
 the value_ private member, where value_ = (mu, log(omega), sigma) and tau = 1 / omega.

 The prior on theta is assumed to be uniform on theta, subject to the an upper bound
 on Var(Y(t)) and omega. The default value of the upper bound on Var(Y(t)) was chosen
 to be 6.9 (i.e., three orders of magnitude when Y(t) is the logarithm of some quantity),
 but this may be overriden through the use of the SetPrior method. The upper bound on
 omega is fixed to be 1 / min(dt), where dt is the vector of time steps.
*/

template <class OmegaType>
class CARMA_Base : public Parameter<arma::vec> {
public:
    // Constructors
    CARMA_Base() {}
    CARMA_Base(bool track, std::string name, std::vector<double> time, std::vector<double> y, std::vector<double> yerr,
               double temperature=1.0) : Parameter<arma::vec>(track, name, temperature)
    {
        // default is to do Bayesian inference
        ignore_prior_ = false;

        // Set the degrees of freedom for the prior on the measurement error scaling parameter
        measerr_dof_ = 50;

        // convert input data to armadillo vectors
        y_  = arma::conv_to<arma::vec>::from(y);
        time_ = arma::conv_to<arma::vec>::from(time);
        yerr_ = arma::conv_to<arma::vec>::from(yerr);

        // default prior bounds on the standard deviation of the time series
        SetPrior(10.0 * sqrt(arma::var(y_)));
    }

    virtual arma::vec StartingValue() = 0;

    std::string StringValue()
    {
        std::stringstream ss;

        ss << log_posterior_;
        for (int i=0; i<value_.n_elem; i++) {
            ss << " " << value_(i);
        }

        std::string theta_str = ss.str();
        return theta_str;
    }

    void Save(arma::vec& new_value)
    {
        // new carma value ---> value_
        value_ = new_value;

        // Update the log-posterior using this new value of theta.
        //
        // IMPORTANT: This assumes that the Kalman filter was calculated
        // using the value of new_value.
        //
        log_posterior_ = 0.0;
        double mu = new_value(2);
        for (int i=0; i<time_.n_elem; i++) {
            double ycent = y_(i) - pKFilter_->mean(i) - mu;
            log_posterior_ += -0.5 * log(pKFilter_->var(i)) - 0.5 * ycent * ycent / pKFilter_->var(i);
        }
        log_posterior_ += LogPrior(new_value);

    }

    // extract the lorentzian parameters from the CARMA parameter vector
    virtual OmegaType ExtractAR(arma::vec theta) = 0;
    // extract the moving-average parameters from the CARMA parameter vector
    virtual arma::vec ExtractMA(arma::vec theta) = 0;
    // extract the variance in the driving noise from the CARMA parameter vector
    virtual double ExtractSigsqr(arma::vec theta) = 0;

    // compute the log-prior of the CARMA parameters
    virtual double LogPrior(arma::vec theta)
    {
        double measerr_scale = theta(1);

        double logprior = -0.5 * measerr_dof_ / measerr_scale -
        (1.0 + measerr_dof_ / 2.0) * log(measerr_scale);

        return logprior;
    }

    virtual void PrintOmega(OmegaType omega) {};

    // compute the log-posterior
    double LogDensity(arma::vec theta)
    {
        // Prior bounds satisfied?
        bool prior_satisfied = CheckPriorBounds(theta);
        if (!prior_satisfied) {
            double logpost = -1.0 * arma::datum::inf;
            return logpost;
        }

        OmegaType omega = ExtractAR(theta);
        arma::vec ma_coefs = ExtractMA(theta);
        double sigsqr = ExtractSigsqr(theta);
        double measerr_scale = theta(1);
        double mu = theta(2);

        // Run the Kalman filter
        pKFilter_->SetSigsqr(sigsqr);
        pKFilter_->SetOmega(omega);
        pKFilter_->SetMA(ma_coefs);
        arma::vec proposed_yerr = sqrt(measerr_scale) * yerr_;
        pKFilter_->SetTimeSeriesErr(proposed_yerr);
        arma::vec ycent = y_ - mu;
        pKFilter_->SetTimeSeries(ycent);
        try {
            pKFilter_->Filter();
        } catch (std::runtime_error& e) {
            std::cout << "Caught a runtime error when trying to run the Kalman Filter: " << e.what() << std::endl;
            std::cout << "Rejecting this proposal..." << std::endl;
            PrintOmega(omega);
            bool prior_satisfied = CheckPriorBounds(theta);
            std::cout << "Prior satisfied: " << prior_satisfied << std::endl;
            double logpost = -1.0 * arma::datum::inf;
            return logpost;
        }

        // calculate the log-likelihood
        double logpost = 0.0;
        for (int i=0; i<time_.n_elem; i++) {
            double ycent = y_(i) - pKFilter_->mean(i) - mu;
            logpost += -0.5 * log(pKFilter_->var(i)) - 0.5 * ycent * ycent / pKFilter_->var(i);
        }

        logpost += LogPrior(theta);

        return logpost;
    }

    bool virtual CheckPriorBounds(arma::vec theta)
    {
        if (ignore_prior_) {return true;}

        double ysigma = theta(0);
        double measerr_scale = theta(1);
        bool prior_satisfied = true;
        if ( (ysigma > max_stdev_) || (ysigma < 0) ||
            (measerr_scale < 0.5) || (measerr_scale > 2.0) )
        {
            prior_satisfied = false;
        }
        return prior_satisfied;
    }

    // Setters and Getters
    arma::vec GetTime() { return time_; }
    arma::vec GetTimeSeries() { return y_; }
    arma::vec GetTimeSeriesErr() { return yerr_; }
    arma::vec GetKalmanMean() { return value_(2) + pKFilter_->mean; }
    arma::vec GetKalmanVar() { return pKFilter_->var; }
    std::shared_ptr<KalmanFilter<OmegaType> > GetKalmanPtr() { return pKFilter_; }

    virtual void SetPrior(double max_stdev) // set the bounds on the uniform prior
    {
        max_stdev_ = max_stdev;
        arma::vec dt = time_(arma::span(1,time_.n_elem-1)) - time_(arma::span(0,time_.n_elem-2));
        max_freq_ = 1.0 / dt.min();
        min_freq_ = 1.0 / (time_.max() - time_.min());
    }

    // Return a copy of the MCMC samples
    std::vector<std::vector<double> > getSamples() {
        int nx = samples_.size();
        int ny = samples_[0].n_elem;
        std::vector<std::vector<double> > samples(nx,std::vector<double>(ny));
        for (int i = 0; i < nx; i++) {
            samples[i] = arma::conv_to<std::vector<double> >::from(samples_[i]);
        }
        return samples;
    }

    // grab the log-prior and log-posterior for a std::vector input
    double getLogPrior(std::vector<double> theta)
    {
        arma::vec armaVec = arma::conv_to<arma::vec>::from(theta);
        return LogPrior(armaVec);
    }
    double getLogDensity(std::vector<double> theta)
    {
        arma::vec armaVec = arma::conv_to<arma::vec>::from(theta);
        return LogDensity(armaVec);
    }

    // set flag for maximum-likelihood estimation
    void SetMLE(bool ignore_prior) {ignore_prior_ = ignore_prior;}

protected:
    // time series data
    arma::vec time_;
    arma::vec y_;
    arma::vec yerr_;
    // pointer to Kalman Filter object. The Kalman filter is the workhorse behind the likelihood calculations.
    std::shared_ptr<KalmanFilter<OmegaType> > pKFilter_;
    // prior parameters
    double max_stdev_; // Maximum value of the standard deviation of the CAR(1) process
	double max_freq_; // Maximum value of omega = 1 / tau
	double min_freq_; // Minimum value of omega = 1 / tau
	int measerr_dof_; // Degrees of freedom for prior on measurement error scaling parameter
    bool ignore_prior_; // If true, then do maximum-likelihood estimation
};

// class for a CAR(1) process
class CAR1 : public CARMA_Base<double> {

public:
	// Constructors //
    CAR1() {}
	CAR1(bool track, std::string name, std::vector<double> time, std::vector<double> y, std::vector<double> yerr,
         double temperature=1.0) : CARMA_Base<double>(track, name, time, y, yerr, temperature)
    {
        pKFilter_ = std::make_shared<KalmanFilter1>(time_, y_, yerr_);
        // Set the size of the parameter vector theta=(mu,sigma,measerr_scale,log(omega))
        value_.set_size(4);
    }

    // extract the AR parameters from the parameter vector
    double ExtractAR(arma::vec theta) { return exp(theta(3)); }
    arma::vec ExtractMA(arma::vec theta) { return arma::zeros<arma::vec>(1); }

    // generate starting values of the CAR(1) parameters
	arma::vec StartingValue();
    arma::vec SetStartingValue(arma::vec init);

    // return the variance of a CAR(1) process
    double ExtractSigsqr(arma::vec theta) {
        return 2.0 * theta(0) * theta(0) * exp(theta(3));
    }

	// Set the bounds on the uniform prior.
    bool CheckPriorBounds(arma::vec theta);
};

/*
 Continuous time autoregressive process of order p.
*/

class CARp : public CARMA_Base<arma::cx_vec> {
public:
    // Constructor
    CARp() {}
    CARp(bool track, std::string name, std::vector<double> time, std::vector<double> y, std::vector<double> yerr, int p,
         double temperature=1.0): CARMA_Base<arma::cx_vec>(track, name, time, y, yerr, temperature), p_(p)
	{
        pKFilter_ = std::make_shared<KalmanFilterp>(time_, y_, yerr_);
		value_.set_size(p_+3);
        ma_coefs_ = arma::zeros(p);
        ma_coefs_(0) = 1.0;
        order_lorentzians_ = true;
        pKFilter_->SetMA(ma_coefs_);
	}

    // calculate the roots of the AR(p) polynomial from the CAR(p) process parameters
    arma::cx_vec ARRoots(arma::vec theta);

    // Return the starting value and set log_posterior_
	arma::vec StartingValue();
    arma::vec SetStartingValue(arma::vec init);
     // return the starting values for the AR and MA parameters
    arma::vec StartingAR();

    // extract the lorentzian parameters from the CARMA parameter vector
    arma::cx_vec ExtractAR(arma::vec theta) {
        return ARRoots(theta);
    }
    // extract the moving-average parameters from the CARMA parameter vector
    arma::vec ExtractMA(arma::vec theta) { return ma_coefs_; }

    double ExtractSigsqr(arma::vec theta) {
        arma::cx_vec ar_roots = ARRoots(theta);
        return theta(0) * theta(0) / Variance(ar_roots, ma_coefs_, 1.0);
    }

    // Calculate the variance of the CAR(p) process
    double Variance(arma::cx_vec alpha_roots, arma::vec ma_coefs, double sigma, double dt=0.0);

    // Set the bounds on the uniform prior.
    bool CheckPriorBounds(arma::vec theta);

    void PrintOmega(arma::cx_vec omega) {
        omega.print("AR Roots:");
    }

protected:
    int p_; // Order of the CAR(p) process
    bool order_lorentzians_; // force the lorentzian centroids to be in order?
private:
    arma::vec ma_coefs_;
};

/*
 Same as CARp class, but using the Belcher et al. (1994) parameterization for the moving average coefficients.
 */
class ZCAR : public CARp
{
public:
    // constructor //
    ZCAR() {}
    ZCAR(bool track, std::string name, std::vector<double> time, std::vector<double> y, std::vector<double> yerr, int p,
         double temperature=1.0) : CARp(track, name, time, y, yerr, p, temperature)
    {
        // set value of kappa
        arma::vec dt = time_(arma::span(1,time_.n_elem-1)) - time_(arma::span(0,time_.n_elem-2));
        kappa_ = 1.0 / dt.min();
        // set the moving average coefficients
        ma_coefs_ = arma::zeros(p_);
        ma_coefs_(0) = 1.0;
        for (int i=1; i<p_; i++) {
            ma_coefs_(i) = boost::math::binomial_coefficient<double>(p_-1, i) / pow(kappa_,i);
        }
        pKFilter_->SetMA(ma_coefs_);
    }
private:
    double kappa_; // minimum frequency resolved by the observation times
    arma::vec ma_coefs_;
};

/*
 Continuous time autoregressive moving average process of order (p,q)
*/

class CARMA : public CARp
{
public:
	// Constructor //
    CARMA() {}
	CARMA(bool track, std::string name, std::vector<double> time, std::vector<double> y, std::vector<double> yerr, int p, int q,
          double temperature=1.0) : CARp(track, name, time, y, yerr, p, temperature), q_(q)
    {
        BOOST_ASSERT_MSG(q < p, "Order of moving average polynomial must be less than order of autoregressive polynomial");
        value_.set_size(p_+q_+3);
    }

    // Return the starting value and set log_posterior_
	arma::vec StartingValue();
    arma::vec SetStartingValue(arma::vec init);

    // return the starting value for the MA coefficients
    arma::vec StartingMA();

    // extract the moving-average parameters from the CARMA parameter vector
    arma::vec ExtractMA(arma::vec theta);

    double ExtractSigsqr(arma::vec theta) {
        arma::cx_vec ar_roots = ARRoots(theta);
        arma::vec ma_coefs = ExtractMA(theta);
        return theta(0) * theta(0) / Variance(ar_roots, ma_coefs, 1.0);
    }

private:
    int q_; // order of moving average polynomial
};

/*
 CARMA(p,p-1) model using the z-transformed parameterization (Belcher et al. 1994). This is the same as the ZCAR model, except
 that kappa is a free parameter for the ZCARMA model.
 */

class ZCARMA : public CARp
{
public:
    ZCARMA() {}
    ZCARMA(bool track, std::string name, std::vector<double> time, std::vector<double> y, std::vector<double> yerr, int p,
           double temperature=1.0) : CARp(track, name, time, y, yerr, p, temperature)
    {
        value_.set_size(p_+4);
        // set default boundaries on kappa
        arma::vec dt = time_(arma::span(1,time_.n_elem-1)) - time_(arma::span(0,time_.n_elem-2));
        kappa_high_ = 1.0 / dt.min();
        // kappa_low_ = 0.9 / dt.min();
        // kappa_low_ = 1.0 / (time_.max() - time_.min());
        kappa_low_ = std::max(1.0 / (time_.max() - time_.min()), 1.0 / (10.0 * arma::median(dt)));
    }

    // Return the starting value and set log_posterior_
	arma::vec StartingValue();
    arma::vec SetStartingValue(arma::vec init);
     // Return the starting value for the kappa parameter
    double StartingKappa();

    // extract the moving-average parameters from the CARMA parameter vector
    arma::vec ExtractMA(arma::vec theta);

    double ExtractSigsqr(arma::vec theta) {
        arma::cx_vec ar_roots = ARRoots(theta);
        arma::vec ma_coefs = ExtractMA(theta);
        return theta(0) * theta(0) / Variance(ar_roots, ma_coefs, 1.0);
    }

    // Set bounds on kappa
    void SetKappaBounds(double kappa_low, double kappa_high) {
        kappa_low_ = kappa_low;
        kappa_high_ = kappa_high;
    }

    // compute the log-prior of the ZCARMA parameters
    double LogPrior(arma::vec theta)
    {
        // first compute prior for measurement error scaling parameter
        double measerr_scale = theta(1);
        double logprior = -0.5 * measerr_dof_ / measerr_scale -
        (1.0 + measerr_dof_ / 2.0) * log(measerr_scale);

        // now compute prior on x = logit(kappa_norm), assuming a uniform prior on kappa
        double logit_kappa = theta(p_+3);
        logprior += -logit_kappa - 2.0 * log(1.0 + exp(-logit_kappa));

        return logprior;
    }

private:
    double kappa_low_, kappa_high_; // prior bounds on the kappa parameter
};

/********************************
	FUNCTION PROTOTYPES
********************************/

double logit(double x);
double inv_logit(double x);

// Check if all of the roots are unique within some fractional tolerance
bool unique_roots(arma::cx_vec roots, double tolerance);

// Return the coefficients of a polynomial given its roots.
arma::vec polycoefs(arma::cx_vec roots);

#endif


#pragma once
#include <QtWidgets>
#include <Eigen/Dense>
#include <array>
#include "typedefs.h"
#include "graph_typedefs.h"
#include <vector>
#include "TopoGraphEmbedding.h"
class ImageQuiverViewer : public QLabel {
	Q_OBJECT

public:
	ImageQuiverViewer(QWidget * parent = Q_NULLPTR);
	~ImageQuiverViewer();

	template <typename T>
	QPointF modelToScreen(const T & p)
	{
		T result = (p + T(0.5, 0.5))*scale;
		return{ result.x(), result.y() };
	}
	void setRoots(const std::array<Eigen::MatrixXcd, 2>& newRoots);
	void setExtraRoots(const std::array<Eigen::MatrixXcd, 2>& newRoots);
	void setPolys(const std::vector<MyPolyline>& newPolys);
	void drawRoots(const std::array<Eigen::MatrixXcd, 2>& thoseOnes, QPainter & painter);
	void drawGraphs(QPainter& painter);
	void drawPolys(QPainter & painter, const std::vector<MyPolyline>& curves, double width, QColor color);
public:
	double scale;
	std::vector<bool> graphHidden;
	std::vector<G> graphs;
	std::vector<std::string> graphTags;
	std::vector<bool> vectorizationsHidden;
	bool polysHidden;
	bool showCircles;
	bool showIncontractibleLoops;

	std::set<size_t> splitVtx;
	std::vector<std::vector<QPointF>> incontractibleLoops;
	std::unique_ptr<Distances> tmpDistances;
	std::vector<std::vector<MyPolyline>> vectorizations;
protected:
	bool areGraphsVisible();
	void paintEvent(QPaintEvent * event);
	void drawClusters(QPainter & painter);
	virtual void mousePressEvent(QMouseEvent * event);
private:
	std::array<Eigen::MatrixXcd, 2> roots, extraRoots;
	std::vector<MyPolyline> polys;
	std::set<std::pair<int, int>> clustersToDraw;
	std::vector<QColor> colors;
};


/**
 * @file   main_inflow_source.cpp
 * @author Simon Pintarelli <simon@thinkpadX1>
 * @date   Thu Apr 28 00:22:50 CEST 2016
 *
 * @brief  create sources in physical space and export to hdf
 *
 */

// system includes -----------------------------------------------
#include <boost/math/constants/constants.hpp>
#include <boost/program_options.hpp>
#include <iostream>
// own includes --------------------------------------------------
#include <base/eigen2hdf.hpp>
#include <base/init.hpp>
#include <base/timer.hpp>
#include <fft/fft2.hpp>
#include <fft/fft2_r2c.hpp>
#include <ridgelet/init_fftw.hpp>
#include <ridgelet/ridgelet_cell_array.hpp>
#include <ridgelet/ridgelet_frame.hpp>
#include <ridgelet/rt.hpp>

#include <boundary_conditions/inflow_bc.hpp>
#include <operators/operators.hpp>
#include <solver/cg.hpp>
#include <solver/ridgelet_solver.hpp>
#include <spectral/quadrature/gauss_hermite_roots.hpp>

using namespace std;
// typedef FFTr2c<PlannerR2C> fft_t;
// typedef RT<RidgeletFrame, fft_t> RT_t;
// typedef RT_t::array_t array_t;
// typedef RT_t::complex_array_t complex_array_t;
// typedef RT_t::rt_coeff_t rt_coeff_t;

const double Lx = 1.2;
const double Ly = 1.2;

// inflow values
const double ql = 0.5;
const double qt = 1.0;

int main(int argc, char *argv[])
{
  SOURCE_INFO();

  namespace po = boost::program_options;

  unsigned int N;
  unsigned int K;

  po::options_description options("options");
  options.add_options()("help", "produce help message")
      ("size,N", po::value<unsigned int>(&N)->default_value(128), "grid size")
      ("deg,K", po::value<unsigned int>(&K)->default_value(10), "deg");
  po::variables_map vm;
  po::store(po::parse_command_line(argc, argv, options), vm);
  po::notify(vm);

  if (vm.count("help")) {
    std::cout << options << "\n";
    return 0;
  }

  cout << "CMD::";
  for (int i = 0; i < argc; ++i) {
    cout << argv[i] << " ";
  }
  cout << "\n";

  const unsigned int Nx = N;
  const unsigned int Ny = N;
  cout << "Nx: " << Nx << "\n";
  cout << "Ny: " << Ny << "\n";
  cout << "K:  " << K << "\n";
  cout << "ql: " << ql << "\n";
  cout << "qt: " << qt << "\n";
  // fft_t fft;
  // init_fftw(fft, FFTW_MEASURE, rf);
  // fft.get_plan().create_and_get_plan(f*Ny, f*Nx, PlannerR2C::INV);
  // fft.get_plan().create_and_get_plan(f*Ny, f*Nx, PlannerR2C::FWD);
  std::vector<double> qi(K);
  boltzmann::gauss_hermite_roots(qi, K);
  Eigen::ArrayXd xi = Eigen::ArrayXd::LinSpaced(Nx + 1, 0, Lx).segment(0, Nx);
  Eigen::ArrayXd yi = Eigen::ArrayXd::LinSpaced(Ny + 1, 0, Ly).segment(0, Ny);

  typedef Eigen::Array<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> array_t;

  for (int i = 0; i < K; ++i) {
    cout << qi[i] << "\t";
  }
  cout << "\n";

  hid_t file = H5Fcreate("inflow_source.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
  array_t X = xi.transpose().replicate(Ny, 1);
  array_t Y = yi.replicate(1, Nx);
#pragma omp parallel for
  for (int qx = 0; qx < K; ++qx) {
    for (int qy = 0; qy < K; ++qy) {
      const double vx = qi[qx];
      const double vy = qi[qy];
      array_t Q(Ny, Nx);
      make_inflow_source(Q, vx, vy, Lx, Ly, ql, qt);
      Q = ((X > 1 || Y > 1)).select(Q, array_t::Zero(Ny, Nx));

#pragma omp critical
      {
        eigen2hdf::save(
            file, boost::lexical_cast<string>(qx) + "_" + boost::lexical_cast<string>(qy), Q);
      }
    }
  }
  H5Fclose(file);

  return 0;
}


//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#define NT2_UNIT_MODULE "boost::simd::constants real"

#include <boost/simd/include/constants/real.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>

////////////////////////////////////////////////////////////////////////////////
// Test value of real constants for every base real types
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE_TPL  (  real_value, BOOST_SIMD_REAL_TYPES )
{
  NT2_TEST_EQUAL( boost::simd::Mhalf<T>()       , static_cast<T>(-1./2. ) );
  NT2_TEST_EQUAL( boost::simd::Mzero<T>()       , static_cast<T>(-0.    ) );
  NT2_TEST_EQUAL( boost::simd::Half<T>()        , static_cast<T>(1./2.  ) );
  NT2_TEST_EQUAL( boost::simd::Third<T>()       , static_cast<T>(1./3.  ) );
  NT2_TEST_EQUAL( boost::simd::Quarter<T>()     , static_cast<T>(1./4.  ) );
  NT2_TEST_EQUAL( boost::simd::Twotom10<T>()    , static_cast<T>(9.765625e-4) );
  NT2_TEST_EQUAL( boost::simd::Pi<T>()          , static_cast<T>(3.1415926535897930) );
  NT2_TEST_EQUAL( boost::simd::Sqrt_2o_2<T>()     , static_cast<T>(7.071067811865476e-1) );
  NT2_TEST_EQUAL( boost::simd::Gold<T>()        , static_cast<T>(1.6180339887498950) );
  NT2_TEST_EQUAL( boost::simd::Cgold<T>()       , static_cast<T>(3.8196601125010515e-1) );
}

NT2_TEST_CASE_TPL( real_value_int, BOOST_SIMD_INTEGRAL_TYPES )
{
  NT2_TEST_EQUAL( boost::simd::Mhalf<T>()       , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Mzero<T>()       , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Half<T>()        , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Third<T>()       , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Quarter<T>()     , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Twotom10<T>()    , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Pi<T>()          , static_cast<T>(3) );
  NT2_TEST_EQUAL( boost::simd::Sqrt_2<T>()      , static_cast<T>(1) );
  NT2_TEST_EQUAL( boost::simd::Sqrt_2o_2<T>()     , static_cast<T>(0) );
  NT2_TEST_EQUAL( boost::simd::Gold<T>()        , static_cast<T>(1) );
  NT2_TEST_EQUAL( boost::simd::Cgold<T>()       , static_cast<T>(0) );
}

////////////////////////////////////////////////////////////////////////////////
// Test type dependant values
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE(type_dependant_real)
{
  NT2_TEST_EQUAL( boost::simd::Twotonmb<double>()    , 4503599627370496. );
  NT2_TEST_EQUAL( boost::simd::Splitfactor<double>(), 134217728.        );
  NT2_TEST_EQUAL( boost::simd::Twotonmb<float>()     , 8388608.f         );
  NT2_TEST_EQUAL( boost::simd::Splitfactor<float>() , 8192.f            );
}

NT2_TEST_CASE(type_dependant_const)
{
  NT2_TEST_EQUAL( (boost::simd::Const<double,0x3FF3BE76C8B43958LL>()), 1.234   );
  NT2_TEST_EQUAL( (boost::simd::Const<float,0x3F9DF3B6>())           , 1.234f );
}

////////////////////////////////////////////////////////////////////////////////
// Test real_constant for every base types
////////////////////////////////////////////////////////////////////////////////
NT2_TEST_CASE_TPL  (  real_constant, (double)(float) )
{
  NT2_TEST_EQUAL( (boost::simd::real_constant < T , 0x3FF3BE76C8B43958LL
                                          , 0x3F9DF3B6
                                      >()
                  )
                , static_cast<T>(1.234)
                );
}

NT2_TEST_CASE(double_constant)
{
  NT2_TEST_EQUAL((boost::simd::double_constant<double,0x3FF3BE76C8B43958LL>()), 1.234);
}

NT2_TEST_CASE(single_constant)
{
  NT2_TEST_EQUAL((boost::simd::single_constant<float,0x3F9DF3B6>()),1.234f);
}


/* Author: Wolfgang Bangerth, University of Heidelberg, 2000 */

/*    $Id: step-8.cc 27657 2012-11-21 13:19:08Z bangerth $       */
/*                                                                */
/*    Copyright (C) 2000-2004, 2006-2008, 2010-2012 by the deal.II authors */
/*                                                                */
/*    This file is subject to QPL and may not be  distributed     */
/*    without copyright and license information. Please refer     */
/*    to the file deal.II/doc/license.html for the  text  and     */
/*    further information on this license.                        */

// @sect3{Include files}

// As usual, the first few include files are already known, so we will not
// comment on them further.
#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/base/logstream.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>
#include <deal.II/lac/constraint_matrix.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_refinement.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/grid/tria_boundary_lib.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_accessor.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>
#include <deal.II/numerics/data_out.h>
#include <deal.II/numerics/error_estimator.h>

// In this example, we need vector-valued finite elements. The support for
// these can be found in the following include file:
#include <deal.II/fe/fe_system.h>
// We will compose the vector-valued finite elements from regular Q1 elements
// which can be found here, as usual:
#include <deal.II/fe/fe_q.h>

// This again is C++:
#include <fstream>
#include <iostream>

// The last step is as in previous programs. In particular, just like in
// step-7, we pack everything that's specific to this program into a namespace
// of its own.
namespace Step8
{
  using namespace dealii;

  // @sect3{The ElasticProblem class template}

  // The main class is, except for its name, almost unchanged with respect to
  // the step-6 example.
  //
  // The only change is the use of a different class for the fe
  // variable: Instead of a concrete finite element class such as
  // FE_Q, we now use a more generic one,
  // FESystem. In fact, FESystem is not really a
  // finite element itself in that it does not implement shape functions of
  // its own.  Rather, it is a class that can be used to stack several other
  // elements together to form one vector-valued finite element. In our case,
  // we will compose the vector-valued element of FE_Q(1)
  // objects, as shown below in the constructor of this class.
  template <int dim>
  class ElasticProblem
  {
  public:
    ElasticProblem ();
    ~ElasticProblem ();
    void run ();

  private:
    void setup_system ();
    void assemble_system ();
    void solve ();
    void refine_grid ();
    void output_results (const unsigned int cycle) const;

    Triangulation<dim>   triangulation;
    DoFHandler<dim>      dof_handler;

    FESystem<dim>        fe;

    ConstraintMatrix     hanging_node_constraints;

    SparsityPattern      sparsity_pattern;
    SparseMatrix<double> system_matrix;

    Vector<double>       solution;
    Vector<double>       system_rhs;
  };

  // @sect3{Right hand side values}

  // Before going over to the implementation of the main class, we declare and
  // define the class which describes the right hand side. This time, the
  // right hand side is vector-valued, as is the solution, so we will describe
  // the changes required for this in some more detail.
  //
  // The first thing is that vector-valued functions have to have a
  // constructor, since they need to pass down to the base class of how many
  // components the function consists. The default value in the constructor of
  // the base class is one (i.e.: a scalar function), which is why we did not
  // need not define a constructor for the scalar function used in previous
  // programs.
  template <int dim>
  class RightHandSide :  public Function<dim>
  {
  public:
    RightHandSide ();

    // The next change is that we want a replacement for the
    // value function of the previous examples. There, a second
    // parameter component was given, which denoted which
    // component was requested. Here, we implement a function that returns the
    // whole vector of values at the given place at once, in the second
    // argument of the function. The obvious name for such a replacement
    // function is vector_value.
    //
    // Secondly, in analogy to the value_list function, there is
    // a function vector_value_list, which returns the values of
    // the vector-valued function at several points at once:
    virtual void vector_value (const Point<dim> &p,
                               Vector<double>   &values) const;

    virtual void vector_value_list (const std::vector<Point<dim> > &points,
                                    std::vector<Vector<double> >   &value_list) const;
  };

  // This is the constructor of the right hand side class. As said above, it
  // only passes down to the base class the number of components, which is
  // dim in the present case (one force component in each of the
  // dim space directions).
  //
  // Some people would have moved the definition of such a short function
  // right into the class declaration. We do not do that, as a matter of
  // style: the deal.II style guides require that class declarations contain
  // only declarations, and that definitions are always to be found
  // outside. This is, obviously, as much as matter of taste as indentation,
  // but we try to be consistent in this direction.
  template <int dim>
  RightHandSide<dim>::RightHandSide ()
    :
    Function<dim> (dim)
  {}

  // Next the function that returns the whole vector of values at the point
  // p at once.
  //
  // To prevent cases where the return vector has not previously been set to
  // the right size we test for this case and otherwise throw an exception at
  // the beginning of the function. Note that enforcing that output arguments
  // already have the correct size is a convention in deal.II, and enforced
  // almost everywhere. The reason is that we would otherwise have to check at
  // the beginning of the function and possibly change the size of the output
  // vector. This is expensive, and would almost always be unnecessary (the
  // first call to the function would set the vector to the right size, and
  // subsequent calls would only have to do redundant checks). In addition,
  // checking and possibly resizing the vector is an operation that can not be
  // removed if we can't rely on the assumption that the vector already has
  // the correct size; this is in contract to the Assert call
  // that is completely removed if the program is compiled in optimized mode.
  //
  // Likewise, if by some accident someone tried to compile and run the
  // program in only one space dimension (in which the elastic equations do
  // not make much sense since they reduce to the ordinary Laplace equation),
  // we terminate the program in the second assertion. The program will work
  // just fine in 3d, however.
  template <int dim>
  inline
  void RightHandSide<dim>::vector_value (const Point<dim> &p,
                                         Vector<double>   &values) const
  {
    Assert (values.size() == dim,
            ExcDimensionMismatch (values.size(), dim));
    Assert (dim >= 2, ExcNotImplemented());

    // The rest of the function implements computing force values. We will use
    // a constant (unit) force in x-direction located in two little circles
    // (or spheres, in 3d) around points (0.5,0) and (-0.5,0), and y-force in
    // an area around the origin; in 3d, the z-component of these centers is
    // zero as well.
    //
    // For this, let us first define two objects that denote the centers of
    // these areas. Note that upon construction of the Point
    // objects, all components are set to zero.
    Point<dim> point_1, point_2;
    point_1(0) = 0.5;
    point_2(0) = -0.5;

    // If now the point p is in a circle (sphere) of radius 0.2
    // around one of these points, then set the force in x-direction to one,
    // otherwise to zero:
    if (((p-point_1).square() < 0.2*0.2) ||
        ((p-point_2).square() < 0.2*0.2))
      values(0) = 1;
    else
      values(0) = 0;

    // Likewise, if p is in the vicinity of the origin, then set
    // the y-force to 1, otherwise to zero:
    if (p.square() < 0.2*0.2)
      values(1) = 1;
    else
      values(1) = 0;
  }

  // Now, this is the function of the right hand side class that returns the
  // values at several points at once. The function starts out with checking
  // that the number of input and output arguments is equal (the sizes of the
  // individual output vectors will be checked in the function that we call
  // further down below). Next, we define an abbreviation for the number of
  // points which we shall work on, to make some things simpler below.
  template <int dim>
  void RightHandSide<dim>::vector_value_list (const std::vector<Point<dim> > &points,
                                              std::vector<Vector<double> >   &value_list) const
  {
    Assert (value_list.size() == points.size(),
            ExcDimensionMismatch (value_list.size(), points.size()));

    const unsigned int n_points = points.size();

    // Finally we treat each of the points. In one of the previous examples,
    // we have explained why the
    // value_list/vector_value_list function had
    // been introduced: to prevent us from calling virtual functions too
    // frequently. On the other hand, we now need to implement the same
    // function twice, which can lead to confusion if one function is changed
    // but the other is not.
    //
    // We can prevent this situation by calling
    // RightHandSide::vector_value on each point in the input
    // list. Note that by giving the full name of the function, including the
    // class name, we instruct the compiler to explicitly call this function,
    // and not to use the virtual function call mechanism that would be used
    // if we had just called vector_value. This is important,
    // since the compiler generally can't make any assumptions which function
    // is called when using virtual functions, and it therefore can't inline
    // the called function into the site of the call. On the contrary, here we
    // give the fully qualified name, which bypasses the virtual function
    // call, and consequently the compiler knows exactly which function is
    // called and will inline above function into the present location. (Note
    // that we have declared the vector_value function above
    // inline, though modern compilers are also able to inline
    // functions even if they have not been declared as inline).
    //
    // It is worth noting why we go to such length explaining what we
    // do. Using this construct, we manage to avoid any inconsistency: if we
    // want to change the right hand side function, it would be difficult to
    // always remember that we always have to change two functions in the same
    // way. Using this forwarding mechanism, we only have to change a single
    // place (the vector_value function), and the second place
    // (the vector_value_list function) will always be consistent
    // with it. At the same time, using virtual function call bypassing, the
    // code is no less efficient than if we had written it twice in the first
    // place:
    for (unsigned int p=0; p<n_points; ++p)
      RightHandSide<dim>::vector_value (points[p],
                                        value_list[p]);
  }

  // @sect3{The ElasticProblem class implementation}

  // @sect4{ElasticProblem::ElasticProblem}

  // Following is the constructor of the main class. As said before, we would
  // like to construct a vector-valued finite element that is composed of
  // several scalar finite elements (i.e., we want to build the vector-valued
  // element so that each of its vector components consists of the shape
  // functions of a scalar element). Of course, the number of scalar finite
  // elements we would like to stack together equals the number of components
  // the solution function has, which is dim since we consider
  // displacement in each space direction. The FESystem class can
  // handle this: we pass it the finite element of which we would like to
  // compose the system of, and how often it shall be repeated:

  template <int dim>
  ElasticProblem<dim>::ElasticProblem ()
    :
    dof_handler (triangulation),
    fe (FE_Q<dim>(1), dim)
  {}
  // In fact, the FESystem class has several more constructors
  // which can perform more complex operations than just stacking together
  // several scalar finite elements of the same type into one; we will get to
  // know these possibilities in later examples.

  // @sect4{ElasticProblem::~ElasticProblem}

  // The destructor, on the other hand, is exactly as in step-6:
  template <int dim>
  ElasticProblem<dim>::~ElasticProblem ()
  {
    dof_handler.clear ();
  }

  // @sect4{ElasticProblem::setup_system}

  // Setting up the system of equations is identitical to the function used in
  // the step-6 example. The DoFHandler class and all other
  // classes used here are fully aware that the finite element we want to use
  // is vector-valued, and take care of the vector-valuedness of the finite
  // element themselves. (In fact, they do not, but this does not need to
  // bother you: since they only need to know how many degrees of freedom
  // there are per vertex, line and cell, and they do not ask what they
  // represent, i.e. whether the finite element under consideration is
  // vector-valued or whether it is, for example, a scalar Hermite element
  // with several degrees of freedom on each vertex).
  template <int dim>
  void ElasticProblem<dim>::setup_system ()
  {
    dof_handler.distribute_dofs (fe);
    hanging_node_constraints.clear ();
    DoFTools::make_hanging_node_constraints (dof_handler,
                                             hanging_node_constraints);
    hanging_node_constraints.close ();
    sparsity_pattern.reinit (dof_handler.n_dofs(),
                             dof_handler.n_dofs(),
                             dof_handler.max_couplings_between_dofs());
    DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);

    hanging_node_constraints.condense (sparsity_pattern);

    sparsity_pattern.compress();

    system_matrix.reinit (sparsity_pattern);

    solution.reinit (dof_handler.n_dofs());
    system_rhs.reinit (dof_handler.n_dofs());
  }

  // @sect4{ElasticProblem::assemble_system}

  // The big changes in this program are in the creation of matrix and right
  // hand side, since they are problem-dependent. We will go through that
  // process step-by-step, since it is a bit more complicated than in previous
  // examples.
  //
  // The first parts of this function are the same as before, however: setting
  // up a suitable quadrature formula, initializing an FEValues
  // object for the (vector-valued) finite element we use as well as the
  // quadrature object, and declaring a number of auxiliary arrays. In
  // addition, we declare the ever same two abbreviations:
  // n_q_points and dofs_per_cell. The number of
  // degrees of freedom per cell we now obviously ask from the composed finite
  // element rather than from the underlying scalar Q1 element. Here, it is
  // dim times the number of degrees of freedom per cell of the
  // Q1 element, though this is not explicit knowledge we need to care about:
  template <int dim>
  void ElasticProblem<dim>::assemble_system ()
  {
    QGauss<dim>  quadrature_formula(2);

    FEValues<dim> fe_values (fe, quadrature_formula,
                             update_values   | update_gradients |
                             update_quadrature_points | update_JxW_values);

    const unsigned int   dofs_per_cell = fe.dofs_per_cell;
    const unsigned int   n_q_points    = quadrature_formula.size();

    FullMatrix<double>   cell_matrix (dofs_per_cell, dofs_per_cell);
    Vector<double>       cell_rhs (dofs_per_cell);

    std::vector<unsigned int> local_dof_indices (dofs_per_cell);

    // As was shown in previous examples as well, we need a place where to
    // store the values of the coefficients at all the quadrature points on a
    // cell. In the present situation, we have two coefficients, lambda and
    // mu.
    std::vector<double>     lambda_values (n_q_points);
    std::vector<double>     mu_values (n_q_points);

    // Well, we could as well have omitted the above two arrays since we will
    // use constant coefficients for both lambda and mu, which can be declared
    // like this. They both represent functions always returning the constant
    // value 1.0. Although we could omit the respective factors in the
    // assemblage of the matrix, we use them here for purpose of
    // demonstration.
    ConstantFunction<dim> lambda(1.), mu(1.);

    // Then again, we need to have the same for the right hand side. This is
    // exactly as before in previous examples. However, we now have a
    // vector-valued right hand side, which is why the data type of the
    // rhs_values array is changed. We initialize it by
    // n_q_points elements, each of which is a
    // Vector@<double@> with dim elements.
    RightHandSide<dim>      right_hand_side;
    std::vector<Vector<double> > rhs_values (n_q_points,
                                             Vector<double>(dim));

    // Now we can begin with the loop over all cells:
    typename DoFHandler<dim>::active_cell_iterator cell = dof_handler.begin_active(),
                                                   endc = dof_handler.end();
    for (; cell!=endc; ++cell)
      {
        cell_matrix = 0;
        cell_rhs = 0;

        fe_values.reinit (cell);

        // Next we get the values of the coefficients at the quadrature
        // points. Likewise for the right hand side:
        lambda.value_list (fe_values.get_quadrature_points(), lambda_values);
        mu.value_list     (fe_values.get_quadrature_points(), mu_values);

        right_hand_side.vector_value_list (fe_values.get_quadrature_points(),
                                           rhs_values);

        // Then assemble the entries of the local stiffness matrix and right
        // hand side vector. This follows almost one-to-one the pattern
        // described in the introduction of this example.  One of the few
        // comments in place is that we can compute the number
        // comp(i), i.e. the index of the only nonzero vector
        // component of shape function i using the
        // fe.system_to_component_index(i).first function call
        // below.
        //
        // (By accessing the first variable of the return value
        // of the system_to_component_index function, you might
        // already have guessed that there is more in it. In fact, the
        // function returns a std::pair@<unsigned int, unsigned
        // int@>, of which the first element is comp(i)
        // and the second is the value base(i) also noted in the
        // introduction, i.e.  the index of this shape function within all the
        // shape functions that are nonzero in this component,
        // i.e. base(i) in the diction of the introduction. This
        // is not a number that we are usually interested in, however.)
        //
        // With this knowledge, we can assemble the local matrix
        // contributions:
        for (unsigned int i=0; i<dofs_per_cell; ++i)
          {
            const unsigned int
            component_i = fe.system_to_component_index(i).first;

            for (unsigned int j=0; j<dofs_per_cell; ++j)
              {
                const unsigned int
                component_j = fe.system_to_component_index(j).first;

                for (unsigned int q_point=0; q_point<n_q_points;
                     ++q_point)
                  {
                    cell_matrix(i,j)
                    +=
                      // The first term is (lambda d_i u_i, d_j v_j) + (mu d_i
                      // u_j, d_j v_i).  Note that
                      // shape_grad(i,q_point) returns the
                      // gradient of the only nonzero component of the i-th
                      // shape function at quadrature point q_point. The
                      // component comp(i) of the gradient, which
                      // is the derivative of this only nonzero vector
                      // component of the i-th shape function with respect to
                      // the comp(i)th coordinate is accessed by the appended
                      // brackets.
                      (
                        (fe_values.shape_grad(i,q_point)[component_i] *
                         fe_values.shape_grad(j,q_point)[component_j] *
                         lambda_values[q_point])
                        +
                        (fe_values.shape_grad(i,q_point)[component_j] *
                         fe_values.shape_grad(j,q_point)[component_i] *
                         mu_values[q_point])
                        +
                        // The second term is (mu nabla u_i, nabla v_j).  We
                        // need not access a specific component of the
                        // gradient, since we only have to compute the scalar
                        // product of the two gradients, of which an
                        // overloaded version of the operator* takes care, as
                        // in previous examples.
                        //
                        // Note that by using the ?: operator, we only do this
                        // if comp(i) equals comp(j), otherwise a zero is
                        // added (which will be optimized away by the
                        // compiler).
                        ((component_i == component_j) ?
                         (fe_values.shape_grad(i,q_point) *
                          fe_values.shape_grad(j,q_point) *
                          mu_values[q_point])  :
                         0)
                      )
                      *
                      fe_values.JxW(q_point);
                  }
              }
          }

        // Assembling the right hand side is also just as discussed in the
        // introduction:
        for (unsigned int i=0; i<dofs_per_cell; ++i)
          {
            const unsigned int
            component_i = fe.system_to_component_index(i).first;

            for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
              cell_rhs(i) += fe_values.shape_value(i,q_point) *
                             rhs_values[q_point](component_i) *
                             fe_values.JxW(q_point);
          }

        // The transfer from local degrees of freedom into the global matrix
        // and right hand side vector does not depend on the equation under
        // consideration, and is thus the same as in all previous
        // examples. The same holds for the elimination of hanging nodes from
        // the matrix and right hand side, once we are done with assembling
        // the entire linear system:
        cell->get_dof_indices (local_dof_indices);
        for (unsigned int i=0; i<dofs_per_cell; ++i)
          {
            for (unsigned int j=0; j<dofs_per_cell; ++j)
              system_matrix.add (local_dof_indices[i],
                                 local_dof_indices[j],
                                 cell_matrix(i,j));

            system_rhs(local_dof_indices[i]) += cell_rhs(i);
          }
      }

    hanging_node_constraints.condense (system_matrix);
    hanging_node_constraints.condense (system_rhs);

    // The interpolation of the boundary values needs a small modification:
    // since the solution function is vector-valued, so need to be the
    // boundary values. The ZeroFunction constructor accepts a
    // parameter that tells it that it shall represent a vector valued,
    // constant zero function with that many components. By default, this
    // parameter is equal to one, in which case the ZeroFunction
    // object would represent a scalar function. Since the solution vector has
    // dim components, we need to pass dim as number
    // of components to the zero function as well.
    std::map<unsigned int,double> boundary_values;
    VectorTools::interpolate_boundary_values (dof_handler,
                                              0,
                                              ZeroFunction<dim>(dim),
                                              boundary_values);
    MatrixTools::apply_boundary_values (boundary_values,
                                        system_matrix,
                                        solution,
                                        system_rhs);
  }

  // @sect4{ElasticProblem::solve}

  // The solver does not care about where the system of equations comes, as
  // long as it stays positive definite and symmetric (which are the
  // requirements for the use of the CG solver), which the system indeed
  // is. Therefore, we need not change anything.
  template <int dim>
  void ElasticProblem<dim>::solve ()
  {
    SolverControl           solver_control (1000, 1e-12);
    SolverCG<>              cg (solver_control);

    PreconditionSSOR<> preconditioner;
    preconditioner.initialize(system_matrix, 1.2);

    cg.solve (system_matrix, solution, system_rhs,
              preconditioner);

    hanging_node_constraints.distribute (solution);
  }

  // @sect4{ElasticProblem::refine_grid}

  // The function that does the refinement of the grid is the same as in the
  // step-6 example. The quadrature formula is adapted to the linear elements
  // again. Note that the error estimator by default adds up the estimated
  // obtained from all components of the finite element solution, i.e., it
  // uses the displacement in all directions with the same weight. If we would
  // like the grid to be adapted to the x-displacement only, we could pass the
  // function an additional parameter which tells it to do so and do not
  // consider the displacements in all other directions for the error
  // indicators. However, for the current problem, it seems appropriate to
  // consider all displacement components with equal weight.
  template <int dim>
  void ElasticProblem<dim>::refine_grid ()
  {
    Vector<float> estimated_error_per_cell (triangulation.n_active_cells());

    typename FunctionMap<dim>::type neumann_boundary;
    KellyErrorEstimator<dim>::estimate (dof_handler,
                                        QGauss<dim-1>(2),
                                        neumann_boundary,
                                        solution,
                                        estimated_error_per_cell);

    GridRefinement::refine_and_coarsen_fixed_number (triangulation,
                                                     estimated_error_per_cell,
                                                     0.3, 0.03);

    triangulation.execute_coarsening_and_refinement ();
  }

  // @sect4{ElasticProblem::output_results}

  // The output happens mostly as has been shown in previous examples
  // already. The only difference is that the solution function is vector
  // valued. The DataOut class takes care of this automatically,
  // but we have to give each component of the solution vector a different
  // name.
  template <int dim>
  void ElasticProblem<dim>::output_results (const unsigned int cycle) const
  {
    std::string filename = "solution-";
    filename += ('0' + cycle);
    Assert (cycle < 10, ExcInternalError());

    filename += ".vtk";
    std::ofstream output (filename.c_str());

    DataOut<dim> data_out;
    data_out.attach_dof_handler (dof_handler);

    // As said above, we need a different name for each component of the
    // solution function. To pass one name for each component, a vector of
    // strings is used. Since the number of components is the same as the
    // number of dimensions we are working in, the following
    // switch statement is used.
    //
    // We note that some graphics programs have restriction as to what
    // characters are allowed in the names of variables. The library therefore
    // supports only the minimal subset of these characters that is supported
    // by all programs. Basically, these are letters, numbers, underscores,
    // and some other characters, but in particular no whitespace and
    // minus/hyphen. The library will throw an exception otherwise, at least
    // if in debug mode.
    //
    // After listing the 1d, 2d, and 3d case, it is good style to let the
    // program die if we run upon a case which we did not consider. Remember
    // that the Assert macro generates an exception if the
    // condition in the first parameter is not satisfied. Of course, the
    // condition false can never be satisfied, so the program
    // will always abort whenever it gets to the default statement:
    std::vector<std::string> solution_names;
    switch (dim)
      {
      case 1:
        solution_names.push_back ("displacement");
        break;
      case 2:
        solution_names.push_back ("x_displacement");
        solution_names.push_back ("y_displacement");
        break;
      case 3:
        solution_names.push_back ("x_displacement");
        solution_names.push_back ("y_displacement");
        solution_names.push_back ("z_displacement");
        break;
      default:
        Assert (false, ExcNotImplemented());
      }

    // After setting up the names for the different components of the solution
    // vector, we can add the solution vector to the list of data vectors
    // scheduled for output. Note that the following function takes a vector
    // of strings as second argument, whereas the one which we have used in
    // all previous examples accepted a string there. In fact, the latter
    // function is only a shortcut for the function which we call here: it
    // puts the single string that is passed to it into a vector of strings
    // with only one element and forwards that to the other function.
    data_out.add_data_vector (solution, solution_names);
    data_out.build_patches ();
    data_out.write_vtk (output);
  }

  // @sect4{ElasticProblem::run}

  // The run function does the same things as in step-6, for
  // example. This time, we use the square [-1,1]^d as domain, and we refine
  // it twice globally before starting the first iteration.
  //
  // The reason is the following: we use the Gauss quadrature
  // formula with two points in each direction for integration of the right
  // hand side; that means that there are four quadrature points on each cell
  // (in 2D). If we only refine the initial grid once globally, then there
  // will be only four quadrature points in each direction on the
  // domain. However, the right hand side function was chosen to be rather
  // localized and in that case all quadrature points lie outside the support
  // of the right hand side function. The right hand side vector will then
  // contain only zeroes and the solution of the system of equations is the
  // zero vector, i.e. a finite element function that it zero everywhere. We
  // should not be surprised about such things happening, since we have chosen
  // an initial grid that is totally unsuitable for the problem at hand.
  //
  // The unfortunate thing is that if the discrete solution is constant, then
  // the error indicators computed by the KellyErrorEstimator
  // class are zero for each cell as well, and the call to
  // refine_and_coarsen_fixed_number on the
  // triangulation object will not flag any cells for refinement
  // (why should it if the indicated error is zero for each cell?). The grid
  // in the next iteration will therefore consist of four cells only as well,
  // and the same problem occurs again.
  //
  // The conclusion needs to be: while of course we will not choose the
  // initial grid to be well-suited for the accurate solution of the problem,
  // we must at least choose it such that it has the chance to capture the
  // most striking features of the solution. In this case, it needs to be able
  // to see the right hand side. Thus, we refine twice globally. (Note that
  // the refine_global function is not part of the
  // GridRefinement class in which
  // refine_and_coarsen_fixed_number is declared, for
  // example. The reason is first that it is not an algorithm that computed
  // refinement flags from indicators, but more importantly that it actually
  // performs the refinement, in contrast to the functions in
  // GridRefinement that only flag cells without actually
  // refining the grid.)
  template <int dim>
  void ElasticProblem<dim>::run ()
  {
    for (unsigned int cycle=0; cycle<8; ++cycle)
      {
        std::cout << "Cycle " << cycle << ':' << std::endl;

        if (cycle == 0)
          {
            GridGenerator::hyper_cube (triangulation, -1, 1);
            triangulation.refine_global (2);
          }
        else
          refine_grid ();

        std::cout << "   Number of active cells:       "
                  << triangulation.n_active_cells()
                  << std::endl;

        setup_system ();

        std::cout << "   Number of degrees of freedom: "
                  << dof_handler.n_dofs()
                  << std::endl;

        assemble_system ();
        solve ();
        output_results (cycle);
      }
  }
}

// @sect3{The main function}

// After closing the Step8 namespace in the last line above, the
// following is the main function of the program and is again exactly like in
// step-6 (apart from the changed class names, of course).
int main ()
{
  try
    {
      dealii::deallog.depth_console (0);

      Step8::ElasticProblem<2> elastic_problem_2d;
      elastic_problem_2d.run ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
                << std::endl;
      std::cerr << "Exception on processing: " << std::endl
                << exc.what() << std::endl
                << "Aborting!" << std::endl
                << "----------------------------------------------------"
                << std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
                << std::endl;
      std::cerr << "Unknown exception!" << std::endl
                << "Aborting!" << std::endl
                << "----------------------------------------------------"
                << std::endl;
      return 1;
    }

  return 0;
}