<commit_before>// Copyright Daniel Wallin & Arvid Norberg 2009. Use, modification and distribution is
// subject to 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 <boost/python.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/file_storage.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{
    void set_hash(create_torrent& c, int p, char const* hash)
    {
        c.set_hash(p, sha1_hash(hash));
    }

    void call_python_object(boost::python::object const& obj, int i)
    {
       obj(i);
    }

#ifndef BOOST_NO_EXCEPTIONS
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1));
    }
#else
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        error_code ec;
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1), ec);
    }

    void set_piece_hashes0(create_torrent& c, std::string const & s)
    {
        error_code ec;
        set_piece_hashes(c, s, ec);
    }
#endif

    void add_node(create_torrent& ct, std::string const& addr, int port)
    {
        ct.add_node(std::make_pair(addr, port));
    }

    void add_file(file_storage& ct, file_entry const& fe)
    {
       ct.add_file(fe);
    }
}

void bind_create_torrent()
{
    void (file_storage::*add_file0)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#if TORRENT_USE_WSTRING
    void (file_storage::*add_file1)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#endif

    void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
#if TORRENT_USE_WSTRING
    void (file_storage::*set_name1)(std::wstring const&) = &file_storage::set_name;
#endif

#ifndef BOOST_NO_EXCEPTIONS
    void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
#endif
    void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;

    file_entry (file_storage::*at)(int) const = &file_storage::at;

    class_<file_storage>("file_storage")
        .def("is_valid", &file_storage::is_valid)
        .def("add_file", add_file, arg("entry"))
        .def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#if TORRENT_USE_WSTRING
        .def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#endif
        .def("num_files", &file_storage::num_files)
        .def("at", at)
//        .def("hash", &file_storage::hash)
//        .def("symlink", &file_storage::symlink, return_internal_reference<>())
//        .def("file_index", &file_storage::file_index)
//        .def("file_base", &file_storage::file_base)
//        .def("set_file_base", &file_storage::set_file_base)
//        .def("file_path", &file_storage::file_path)
        .def("total_size", &file_storage::total_size)
        .def("set_num_pieces", &file_storage::set_num_pieces)
        .def("num_pieces", &file_storage::num_pieces)
        .def("set_piece_length", &file_storage::set_piece_length)
        .def("piece_length", &file_storage::piece_length)
        .def("piece_size", &file_storage::piece_size)
        .def("set_name", set_name0)
#if TORRENT_USE_WSTRING
        .def("set_name", set_name1)
#endif
        .def("name", &file_storage::name, return_internal_reference<>())
        ;

    class_<create_torrent>("create_torrent", no_init)
        .def(init<file_storage&>())
        .def(init<file_storage&, torrent_info const&>(arg("ti")))
        .def(init<file_storage&, int, int, int>((arg("storage"), arg("piece_size") = 0
            , arg("pad_file_limit") = -1, arg("flags") = int(libtorrent::create_torrent::optimize))))

        .def("generate", &create_torrent::generate)

        .def("files", &create_torrent::files, return_internal_reference<>())
        .def("set_comment", &create_torrent::set_comment)
        .def("set_creator", &create_torrent::set_creator)
        .def("set_hash", &set_hash)
        .def("add_url_seed", &create_torrent::add_url_seed)
        .def("add_node", &add_node)
        .def("add_tracker", &create_torrent::add_tracker, (arg("announce_url"), arg("tier") = 0))
        .def("set_priv", &create_torrent::set_priv)
        .def("num_pieces", &create_torrent::num_pieces)
        .def("piece_length", &create_torrent::piece_length)
        .def("piece_size", &create_torrent::piece_size)
        .def("priv", &create_torrent::priv)
        ;

    enum_<create_torrent::flags_t>("create_torrent_flags_t")
        .value("optimize", create_torrent::optimize)
        .value("merkle", create_torrent::merkle)
        .value("modification_time", create_torrent::modification_time)
        .value("symlinks", create_torrent::symlinks)
    ;

    def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
    def("set_piece_hashes", set_piece_hashes0);
    def("set_piece_hashes", set_piece_hashes_callback);

}
<commit_msg>fixed typo in python binding<commit_after>// Copyright Daniel Wallin & Arvid Norberg 2009. Use, modification and distribution is
// subject to 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 <boost/python.hpp>
#include <libtorrent/create_torrent.hpp>
#include <libtorrent/file_storage.hpp>
#include "libtorrent/intrusive_ptr_base.hpp"

using namespace boost::python;
using namespace libtorrent;

namespace
{
    void set_hash(create_torrent& c, int p, char const* hash)
    {
        c.set_hash(p, sha1_hash(hash));
    }

    void call_python_object(boost::python::object const& obj, int i)
    {
       obj(i);
    }

#ifndef BOOST_NO_EXCEPTIONS
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1));
    }
#else
    void set_piece_hashes_callback(create_torrent& c, std::string const& p
        , boost::python::object cb)
    {
        error_code ec;
        set_piece_hashes(c, p, boost::bind(call_python_object, cb, _1), ec);
    }

    void set_piece_hashes0(create_torrent& c, std::string const & s)
    {
        error_code ec;
        set_piece_hashes(c, s, ec);
    }
#endif

    void add_node(create_torrent& ct, std::string const& addr, int port)
    {
        ct.add_node(std::make_pair(addr, port));
    }

    void add_file(file_storage& ct, file_entry const& fe)
    {
       ct.add_file(fe);
    }
}

void bind_create_torrent()
{
    void (file_storage::*add_file0)(std::string const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#if TORRENT_USE_WSTRING
    void (file_storage::*add_file1)(std::wstring const&, size_type, int, std::time_t, std::string const&) = &file_storage::add_file;
#endif

    void (file_storage::*set_name0)(std::string const&) = &file_storage::set_name;
#if TORRENT_USE_WSTRING
    void (file_storage::*set_name1)(std::wstring const&) = &file_storage::set_name;
#endif

#ifndef BOOST_NO_EXCEPTIONS
    void (*set_piece_hashes0)(create_torrent&, std::string const&) = &set_piece_hashes;
#endif
    void (*add_files0)(file_storage&, std::string const&, boost::uint32_t) = add_files;

    file_entry (file_storage::*at)(int) const = &file_storage::at;

    class_<file_storage>("file_storage")
        .def("is_valid", &file_storage::is_valid)
        .def("add_file", add_file, arg("entry"))
        .def("add_file", add_file0, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#if TORRENT_USE_WSTRING
        .def("add_file", add_file1, (arg("path"), arg("size"), arg("flags") = 0, arg("mtime") = 0, arg("linkpath") = ""))
#endif
        .def("num_files", &file_storage::num_files)
        .def("at", at)
//        .def("hash", &file_storage::hash)
//        .def("symlink", &file_storage::symlink, return_internal_reference<>())
//        .def("file_index", &file_storage::file_index)
//        .def("file_base", &file_storage::file_base)
//        .def("set_file_base", &file_storage::set_file_base)
//        .def("file_path", &file_storage::file_path)
        .def("total_size", &file_storage::total_size)
        .def("set_num_pieces", &file_storage::set_num_pieces)
        .def("num_pieces", &file_storage::num_pieces)
        .def("set_piece_length", &file_storage::set_piece_length)
        .def("piece_length", &file_storage::piece_length)
        .def("piece_size", &file_storage::piece_size)
        .def("set_name", set_name0)
#if TORRENT_USE_WSTRING
        .def("set_name", set_name1)
#endif
        .def("name", &file_storage::name, return_internal_reference<>())
        ;

    class_<create_torrent>("create_torrent", no_init)
        .def(init<file_storage&>())
        .def(init<torrent_info const&>(arg("ti")))
        .def(init<file_storage&, int, int, int>((arg("storage"), arg("piece_size") = 0
            , arg("pad_file_limit") = -1, arg("flags") = int(libtorrent::create_torrent::optimize))))

        .def("generate", &create_torrent::generate)

        .def("files", &create_torrent::files, return_internal_reference<>())
        .def("set_comment", &create_torrent::set_comment)
        .def("set_creator", &create_torrent::set_creator)
        .def("set_hash", &set_hash)
        .def("add_url_seed", &create_torrent::add_url_seed)
        .def("add_node", &add_node)
        .def("add_tracker", &create_torrent::add_tracker, (arg("announce_url"), arg("tier") = 0))
        .def("set_priv", &create_torrent::set_priv)
        .def("num_pieces", &create_torrent::num_pieces)
        .def("piece_length", &create_torrent::piece_length)
        .def("piece_size", &create_torrent::piece_size)
        .def("priv", &create_torrent::priv)
        ;

    enum_<create_torrent::flags_t>("create_torrent_flags_t")
        .value("optimize", create_torrent::optimize)
        .value("merkle", create_torrent::merkle)
        .value("modification_time", create_torrent::modification_time)
        .value("symlinks", create_torrent::symlinks)
    ;

    def("add_files", add_files0, (arg("fs"), arg("path"), arg("flags") = 0));
    def("set_piece_hashes", set_piece_hashes0);
    def("set_piece_hashes", set_piece_hashes_callback);

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: osl_Socket_tests.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 08:53:55 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

//------------------------------------------------------------------------
// include files
//------------------------------------------------------------------------

#ifndef _OSL_SOCKET_CONST_H_
#include <osl_Socket_Const.h>
#endif

#include <cppunit/simpleheader.hxx>

#ifndef _OSL_SOCKET_HXX_
#include <osl/socket.hxx>
#endif
//------------------------------------------------------------------------
// helper functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// tests cases begins here
//------------------------------------------------------------------------

namespace osl_Socket
{

    class tests : public CppUnit::TestFixture
    {
    public:

        void test_001()
            {
                // _osl_getFullQualifiedDomainName( );
                oslSocketResult aResult;
                rtl::OUString suHostname = osl::SocketAddr::getLocalHostname(&aResult);
                CPPUNIT_ASSERT_MESSAGE("getLocalHostname failed", aResult == osl_Socket_Ok);
            }

        CPPUNIT_TEST_SUITE( tests );
        CPPUNIT_TEST( test_001 );
        CPPUNIT_TEST_SUITE_END();
    };

    CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Socket::tests, "osl_SocketTest");
}

// -----------------------------------------------------------------------------

// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.

/*#if (defined LINUX)

void RegisterAdditionalFunctions( FktRegFuncPtr _pFunc )
{
    // for cover lines in _osl_getFullQualifiedDomainName( )
    // STAR_OVERRIDE_DOMAINNAME is more an internal HACK for 5.2, which should remove from sal
    setenv( "STAR_OVERRIDE_DOMAINNAME", "PRC.Sun.COM", 0 );
}

#else*/

NOADDITIONAL;

//#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.7.234); FILE MERGED 2008/04/01 12:34:15 thb 1.7.234.2: #i85898# Stripping all external header guards 2008/03/31 13:23:52 rt 1.7.234.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: osl_Socket_tests.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

//------------------------------------------------------------------------
// include files
//------------------------------------------------------------------------
#include <osl_Socket_Const.h>

#include <cppunit/simpleheader.hxx>
#include <osl/socket.hxx>
//------------------------------------------------------------------------
// helper functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// tests cases begins here
//------------------------------------------------------------------------

namespace osl_Socket
{

    class tests : public CppUnit::TestFixture
    {
    public:

        void test_001()
            {
                // _osl_getFullQualifiedDomainName( );
                oslSocketResult aResult;
                rtl::OUString suHostname = osl::SocketAddr::getLocalHostname(&aResult);
                CPPUNIT_ASSERT_MESSAGE("getLocalHostname failed", aResult == osl_Socket_Ok);
            }

        CPPUNIT_TEST_SUITE( tests );
        CPPUNIT_TEST( test_001 );
        CPPUNIT_TEST_SUITE_END();
    };

    CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Socket::tests, "osl_SocketTest");
}

// -----------------------------------------------------------------------------

// this macro creates an empty function, which will called by the RegisterAllFunctions()
// to let the user the possibility to also register some functions by hand.

/*#if (defined LINUX)

void RegisterAdditionalFunctions( FktRegFuncPtr _pFunc )
{
    // for cover lines in _osl_getFullQualifiedDomainName( )
    // STAR_OVERRIDE_DOMAINNAME is more an internal HACK for 5.2, which should remove from sal
    setenv( "STAR_OVERRIDE_DOMAINNAME", "PRC.Sun.COM", 0 );
}

#else*/

NOADDITIONAL;

//#endif
<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_LA_SOLVER_EIGEN_ITERATIVE_HH
#define DUNE_STUFF_LA_SOLVER_EIGEN_ITERATIVE_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAVE_EIGEN

#include <Eigen/SparseCore>
#include <Eigen/IterativeLinearSolvers>

#include <dune/common/exceptions.hh>

#include <dune/stuff/la/container/eigen.hh>

#include "../interface.hh"

namespace Dune {
namespace Stuff {
namespace LA {
namespace Solver {
namespace Eigen {

//! provide a Dummy preconditioner that fits the expectatations below
template <class Dummy>
class IdentityPreconditioner : public ::Eigen::IdentityPreconditioner
{};

template< class MatrixImp, class VectorImp, template < class ElementImp > class Preconditioner = IdentityPreconditioner>
class Bicgstab;

template< class ElementImp, template < class ElementImp > class Preconditioner >
class Bicgstab< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                Container::Eigen::DenseVector< ElementImp >,
                Preconditioner>
  : public Interface< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
{
public:
  typedef Interface<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;

  typedef typename BaseType::VectorType VectorType;

  typedef typename BaseType::ElementType ElementType;

  typedef typename BaseType::size_type size_type;

private:
  typedef Preconditioner< ElementType > PreconditionerType;

  typedef ::Eigen::BiCGSTAB< typename MatrixType::BaseType, PreconditionerType > SolverType;

public:
  Bicgstab()
    : initialized_(false)
  {}

  virtual void init(const MatrixType& systemMatrix)
  {
    if (initialized_)
      DUNE_THROW(Dune::InvalidStateException, "\nERROR: init() may only be called once!");
    solver_ = new SolverType(systemMatrix.base());
    initialized_ = true;
  } // virtual void init(...)

  virtual bool apply(const VectorType& rhsVector,
                     VectorType& solutionVector,
                     const size_type maxIter = 5000,
                     const ElementType precision = 1e-12) const
  {
    if (!initialized_)
      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
    solver_->setMaxIterations(maxIter);
    solver_->setTolerance(precision);
    solutionVector.base() = solver_->solve(rhsVector.base());
    const ::Eigen::ComputationInfo info = solver_->info();
    return (info == ::Eigen::Success);
  } // virtual bool apply(...)

private:
  bool initialized_;
  SolverType* solver_;
}; // class BicgstabDiagonal

template< class MatrixImp, class VectorImp >
class BicgstabIncompleteLUT;

template< class ElementImp >
class BicgstabIncompleteLUT<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                              Container::Eigen::DenseVector< ElementImp > >
  : public Bicgstab<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp >,
                      ::Eigen::IncompleteLUT>
{};

template< class MatrixImp, class VectorImp >
class BicgstabDiagonal;

template< class ElementImp >
class BicgstabDiagonal< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                        Container::Eigen::DenseVector< ElementImp > >
  : public Bicgstab<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp >,
                      ::Eigen::DiagonalPreconditioner>
{};

template< class MatrixImp, class VectorImp >
class CG;

//! CG implementation following "van der Vorst - Iterative Methods for Large Linear Systems (2002)" p.44
template< class ElementImp >
class CG< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
          Container::Eigen::DenseVector< ElementImp > >
  : public Interface< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
{
public:
  typedef Interface<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;

  typedef typename BaseType::VectorType VectorType;

  typedef typename BaseType::ElementType ElementType;

  typedef typename BaseType::size_type size_type;

public:
  CG()
    : initialized_(false)
    , systemMatrix_(nullptr)
  {}

  virtual void init(const MatrixType& systemMatrix)
  {
    systemMatrix_ = &(systemMatrix);
    initialized_ = true;
  } // virtual void init(...)

  virtual bool apply(const VectorType& rhsVector,
                     VectorType& solutionVector,
                     const size_type maxIter = 5000,
                     const ElementType precision = 1e-12) const
  {
    if (!initialized_)
      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
    assert(systemMatrix_);
    auto& x_i = solutionVector.base();
    const auto& b = rhsVector.base();
    const auto& A = systemMatrix_->base();
    const int cols = A.cols();
    size_type iteration(1);
    ElementType rho(0), rho_prev(1), beta, alpha;
    const ElementType tolerance = precision * precision * b.squaredNorm();
    typename VectorType::BaseType residuum = b - A * x_i;
    typename VectorType::BaseType correction_p(cols);
    typename VectorType::BaseType correction_q(cols);
    rho = residuum.squaredNorm();
    while (iteration <= maxIter) {
      if (iteration == 1) {
          correction_p = residuum;
      }
      else {
          beta = rho / rho_prev;
          correction_p = residuum + beta * correction_p;
      }
      correction_q.noalias() = A * correction_p;
      alpha = rho / correction_p.dot(correction_q);
      x_i += alpha * correction_p;
      residuum -= alpha * correction_q;
      rho = residuum.squaredNorm();
      if (rho < tolerance)
          return true;
      rho_prev = rho;
    }
    return false;
  } // virtual bool apply(...)

private:
  bool initialized_;
  const MatrixType* systemMatrix_;
}; // class CG

//template< class MatrixImp >
//class CgDiagonal
//  : public Interface< MatrixImp >
//{
//public:
//  typedef Interface< MatrixImp > BaseType;

//  typedef typename BaseType::MatrixType MatrixType;

//  typedef typename BaseType::VectorType VectorType;

//  typedef typename BaseType::ElementType ElementType;

//  typedef typename BaseType::size_type size_type;

//private:
//  typedef ::Eigen::DiagonalPreconditioner< ElementType > PreconditionerType;

//  typedef ::Eigen::ConjugateGradient< typename MatrixType::BaseType, ::Eigen::Lower, PreconditionerType > SolverType;

//public:
//  CgDiagonal()
//    : initialized_(false)
//  {}

//  virtual void init(const MatrixType& systemMatrix)
//  {
//    if (initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: init() may only be called once!");
//    solver_ = new SolverType(systemMatrix.base());
//    initialized_ = true;
//  } // virtual void init(...)

//  virtual bool apply(const VectorType& rhsVector,
//                     VectorType& solutionVector,
//                     const size_type maxIter = 5000,
//                     const ElementType precision = 1e-12) const
//  {
//    if (!initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
//    solver_->setMaxIterations(maxIter);
//    solver_->setTolerance(precision);
//    solutionVector.base() = solver_->solve(rhsVector.base());
//    const ::Eigen::ComputationInfo info = solver_->info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)

//private:
//  bool initialized_;
//  SolverType* solver_;
//}; // class CgDiagonal

//template< class MatrixImp >
//class CgIncompleteLUT
//  : public Interface< MatrixImp >
//{
//public:
//  typedef Interface< MatrixImp > BaseType;

//  typedef typename BaseType::MatrixType MatrixType;

//  typedef typename BaseType::VectorType VectorType;

//  typedef typename BaseType::ElementType ElementType;

//  typedef typename BaseType::size_type size_type;

//private:
//  typedef ::Eigen::IncompleteLUT< ElementType > PreconditionerType;

//  typedef ::Eigen::ConjugateGradient< typename MatrixType::BaseType, ::Eigen::Lower, PreconditionerType > SolverType;

//public:
//  CgIncompleteLUT()
//    : initialized_(false)
//  {}

//  virtual void init(const MatrixType& systemMatrix)
//  {
//    if (initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: init() may only be called once!");
//    solver_ = new SolverType(systemMatrix.base());
//    initialized_ = true;
//  } // virtual void init(...)

//  virtual bool apply(const VectorType& rhsVector,
//                     VectorType& solutionVector,
//                     const size_type maxIter = 5000,
//                     const ElementType precision = 1e-12) const
//  {
//    if (!initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
//    solver_->setMaxIterations(maxIter);
//    solver_->setTolerance(precision);
//    solutionVector.base() = solver_->solve(rhsVector.base());
//    const ::Eigen::ComputationInfo info = solver_->info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)

//private:
//  bool initialized_;
//  SolverType* solver_;
//}; // class CgIncompleteLUT

} // namespace Eigen
} // namespace Solver
} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_STUFF_LA_SOLVER_EIGEN_ITERATIVE_HH
<commit_msg>[la] fixes clang compiler err in bicgstab<commit_after>#ifndef DUNE_STUFF_LA_SOLVER_EIGEN_ITERATIVE_HH
#define DUNE_STUFF_LA_SOLVER_EIGEN_ITERATIVE_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAVE_EIGEN

#include <Eigen/SparseCore>
#include <Eigen/IterativeLinearSolvers>

#include <dune/common/exceptions.hh>

#include <dune/stuff/la/container/eigen.hh>

#include "../interface.hh"

namespace Dune {
namespace Stuff {
namespace LA {
namespace Solver {
namespace Eigen {

//! provide a Dummy preconditioner that fits the expectatations below
template <class Dummy>
class IdentityPreconditioner : public ::Eigen::IdentityPreconditioner
{};

template< class MatrixImp, class VectorImp, template < class ElementImp > class Preconditioner = IdentityPreconditioner>
class Bicgstab;

template< class ElementImp, template < class T > class Preconditioner >
class Bicgstab< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                Container::Eigen::DenseVector< ElementImp >,
                Preconditioner>
  : public Interface< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
{
public:
  typedef Interface<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;

  typedef typename BaseType::VectorType VectorType;

  typedef typename BaseType::ElementType ElementType;

  typedef typename BaseType::size_type size_type;

private:
  typedef Preconditioner< ElementType > PreconditionerType;

  typedef ::Eigen::BiCGSTAB< typename MatrixType::BaseType, PreconditionerType > SolverType;

public:
  Bicgstab()
    : initialized_(false)
  {}

  virtual void init(const MatrixType& systemMatrix)
  {
    if (initialized_)
      DUNE_THROW(Dune::InvalidStateException, "\nERROR: init() may only be called once!");
    solver_ = new SolverType(systemMatrix.base());
    initialized_ = true;
  } // virtual void init(...)

  virtual bool apply(const VectorType& rhsVector,
                     VectorType& solutionVector,
                     const size_type maxIter = 5000,
                     const ElementType precision = 1e-12) const
  {
    if (!initialized_)
      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
    solver_->setMaxIterations(maxIter);
    solver_->setTolerance(precision);
    solutionVector.base() = solver_->solve(rhsVector.base());
    const ::Eigen::ComputationInfo info = solver_->info();
    return (info == ::Eigen::Success);
  } // virtual bool apply(...)

private:
  bool initialized_;
  SolverType* solver_;
}; // class BicgstabDiagonal

template< class MatrixImp, class VectorImp >
class BicgstabIncompleteLUT;

template< class ElementImp >
class BicgstabIncompleteLUT<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                              Container::Eigen::DenseVector< ElementImp > >
  : public Bicgstab<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp >,
                      ::Eigen::IncompleteLUT>
{};

template< class MatrixImp, class VectorImp >
class BicgstabDiagonal;

template< class ElementImp >
class BicgstabDiagonal< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                        Container::Eigen::DenseVector< ElementImp > >
  : public Bicgstab<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp >,
                      ::Eigen::DiagonalPreconditioner>
{};

template< class MatrixImp, class VectorImp >
class CG;

//! CG implementation following "van der Vorst - Iterative Methods for Large Linear Systems (2002)" p.44
template< class ElementImp >
class CG< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
          Container::Eigen::DenseVector< ElementImp > >
  : public Interface< Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
{
public:
  typedef Interface<  Container::Eigen::RowMajorSparseMatrix< ElementImp >,
                      Container::Eigen::DenseVector< ElementImp > >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;

  typedef typename BaseType::VectorType VectorType;

  typedef typename BaseType::ElementType ElementType;

  typedef typename BaseType::size_type size_type;

public:
  CG()
    : initialized_(false)
    , systemMatrix_(nullptr)
  {}

  virtual void init(const MatrixType& systemMatrix)
  {
    systemMatrix_ = &(systemMatrix);
    initialized_ = true;
  } // virtual void init(...)

  virtual bool apply(const VectorType& rhsVector,
                     VectorType& solutionVector,
                     const size_type maxIter = 5000,
                     const ElementType precision = 1e-12) const
  {
    if (!initialized_)
      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
    assert(systemMatrix_);
    auto& x_i = solutionVector.base();
    const auto& b = rhsVector.base();
    const auto& A = systemMatrix_->base();
    const int cols = A.cols();
    size_type iteration(1);
    ElementType rho(0), rho_prev(1), beta, alpha;
    const ElementType tolerance = precision * precision * b.squaredNorm();
    typename VectorType::BaseType residuum = b - A * x_i;
    typename VectorType::BaseType correction_p(cols);
    typename VectorType::BaseType correction_q(cols);
    rho = residuum.squaredNorm();
    while (iteration <= maxIter) {
      if (iteration == 1) {
          correction_p = residuum;
      }
      else {
          beta = rho / rho_prev;
          correction_p = residuum + beta * correction_p;
      }
      correction_q.noalias() = A * correction_p;
      alpha = rho / correction_p.dot(correction_q);
      x_i += alpha * correction_p;
      residuum -= alpha * correction_q;
      rho = residuum.squaredNorm();
      if (rho < tolerance)
          return true;
      rho_prev = rho;
    }
    return false;
  } // virtual bool apply(...)

private:
  bool initialized_;
  const MatrixType* systemMatrix_;
}; // class CG

//template< class MatrixImp >
//class CgDiagonal
//  : public Interface< MatrixImp >
//{
//public:
//  typedef Interface< MatrixImp > BaseType;

//  typedef typename BaseType::MatrixType MatrixType;

//  typedef typename BaseType::VectorType VectorType;

//  typedef typename BaseType::ElementType ElementType;

//  typedef typename BaseType::size_type size_type;

//private:
//  typedef ::Eigen::DiagonalPreconditioner< ElementType > PreconditionerType;

//  typedef ::Eigen::ConjugateGradient< typename MatrixType::BaseType, ::Eigen::Lower, PreconditionerType > SolverType;

//public:
//  CgDiagonal()
//    : initialized_(false)
//  {}

//  virtual void init(const MatrixType& systemMatrix)
//  {
//    if (initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: init() may only be called once!");
//    solver_ = new SolverType(systemMatrix.base());
//    initialized_ = true;
//  } // virtual void init(...)

//  virtual bool apply(const VectorType& rhsVector,
//                     VectorType& solutionVector,
//                     const size_type maxIter = 5000,
//                     const ElementType precision = 1e-12) const
//  {
//    if (!initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
//    solver_->setMaxIterations(maxIter);
//    solver_->setTolerance(precision);
//    solutionVector.base() = solver_->solve(rhsVector.base());
//    const ::Eigen::ComputationInfo info = solver_->info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)

//private:
//  bool initialized_;
//  SolverType* solver_;
//}; // class CgDiagonal

//template< class MatrixImp >
//class CgIncompleteLUT
//  : public Interface< MatrixImp >
//{
//public:
//  typedef Interface< MatrixImp > BaseType;

//  typedef typename BaseType::MatrixType MatrixType;

//  typedef typename BaseType::VectorType VectorType;

//  typedef typename BaseType::ElementType ElementType;

//  typedef typename BaseType::size_type size_type;

//private:
//  typedef ::Eigen::IncompleteLUT< ElementType > PreconditionerType;

//  typedef ::Eigen::ConjugateGradient< typename MatrixType::BaseType, ::Eigen::Lower, PreconditionerType > SolverType;

//public:
//  CgIncompleteLUT()
//    : initialized_(false)
//  {}

//  virtual void init(const MatrixType& systemMatrix)
//  {
//    if (initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: init() may only be called once!");
//    solver_ = new SolverType(systemMatrix.base());
//    initialized_ = true;
//  } // virtual void init(...)

//  virtual bool apply(const VectorType& rhsVector,
//                     VectorType& solutionVector,
//                     const size_type maxIter = 5000,
//                     const ElementType precision = 1e-12) const
//  {
//    if (!initialized_)
//      DUNE_THROW(Dune::InvalidStateException, "\nERROR: please call init() before calling apply()!");
//    solver_->setMaxIterations(maxIter);
//    solver_->setTolerance(precision);
//    solutionVector.base() = solver_->solve(rhsVector.base());
//    const ::Eigen::ComputationInfo info = solver_->info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)

//private:
//  bool initialized_;
//  SolverType* solver_;
//}; // class CgIncompleteLUT

} // namespace Eigen
} // namespace Solver
} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_STUFF_LA_SOLVER_EIGEN_ITERATIVE_HH
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.1  2001/08/21 15:58:42  tng
 * Schema: New files XercesElementWildCard.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <validators/schema/XercesElementWildcard.hpp>

// ---------------------------------------------------------------------------
//  Local methods
// ---------------------------------------------------------------------------

/**
 * XercesElementWildcard is used to check whether two element declarations conflict
 */
/**
 * Check whether two element declarations conflict
 */
bool XercesElementWildcard::conflict(ContentSpecNode::NodeTypes   type1,
                                     QName*                       q1,
                                     ContentSpecNode::NodeTypes   type2,
                                     QName*                       q2,
                                     SubstitutionGroupComparator* comparator)
{
    if (type1 == ContentSpecNode::Leaf &&
        type2 == ContentSpecNode::Leaf) {
        if (comparator->isEquivalentTo(q1, q2) || comparator->isEquivalentTo(q2, q1))
            return true;
    }
    else if (type1 == ContentSpecNode::Leaf) {
        return uriInWildcard(q1, q2->getURI(), type2, comparator);
    }
    else if (type2 == ContentSpecNode::Leaf) {
        return uriInWildcard(q2, q1->getURI(), type1, comparator);
    }
    else {
        return wildcardIntersect(type1, q1->getURI(), type2, q2->getURI());
    }
    return false;
}

bool XercesElementWildcard::uriInWildcard(QName*                       qname,
                                          unsigned int                 wildcard,
                                          ContentSpecNode::NodeTypes   wtype,
                                          SubstitutionGroupComparator* comparator)
{
    if ((wtype & 0x0f)== ContentSpecNode::Any) {
        return true;
    }
    else if ((wtype & 0x0f)== ContentSpecNode::Any_NS) {
        // substitution of "uri" satisfies "wtype:wildcard"
        return comparator->isAllowedByWildcard(qname, wildcard, false);
    }
    else if ((wtype & 0x0f)== ContentSpecNode::Any_Other) {
        // substitution of "uri" satisfies "wtype:wildcard"
        return comparator->isAllowedByWildcard(qname, wildcard, true);
    }

    return false;
}

bool XercesElementWildcard::wildcardIntersect(ContentSpecNode::NodeTypes t1,
                                              unsigned int               w1,
                                              ContentSpecNode::NodeTypes t2,
                                              unsigned int               w2)
{
    if (((w1 & 0x0f) == ContentSpecNode::Any) ||
        ((w2 & 0x0f) == ContentSpecNode::Any)) {
        // if either one is "##any", then intersects
        return true;
    }
    else if (((w1 & 0x0f) == ContentSpecNode::Any_NS) &&
             ((w2 & 0x0f) == ContentSpecNode::Any_NS) &&
             (w1 == w2)) {
        // if both are "some_namespace" and equal, then intersects
        return true;
    }
    else if (((w1 & 0x0f) == ContentSpecNode::Any_Other) &&
             ((w2 & 0x0f) == ContentSpecNode::Any_Other)) {
        // if both are "##other", and equal, then intersects
        return true;
    }
    else if (((((w1 & 0x0f) == ContentSpecNode::Any_NS) &&
               ((w2 & 0x0f) == ContentSpecNode::Any_Other)) ||
              (((w1 & 0x0f) == ContentSpecNode::Any_Other) &&
               ((w2 & 0x0f) == ContentSpecNode::Any_NS))) &&
             (w1 != w2)) {
        return true;
    }
    return false;
}

<commit_msg>typo: the type should be t1/t2, not w1/w2.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 2001 The Apache Software Foundation.  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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 2001, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/*
 * $Log$
 * Revision 1.2  2001/08/22 16:58:27  tng
 * typo: the type should be t1/t2, not w1/w2.
 *
 * Revision 1.1  2001/08/21 15:58:42  tng
 * Schema: New files XercesElementWildCard.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <validators/schema/XercesElementWildcard.hpp>

// ---------------------------------------------------------------------------
//  Local methods
// ---------------------------------------------------------------------------

/**
 * XercesElementWildcard is used to check whether two element declarations conflict
 */
/**
 * Check whether two element declarations conflict
 */
bool XercesElementWildcard::conflict(ContentSpecNode::NodeTypes   type1,
                                     QName*                       q1,
                                     ContentSpecNode::NodeTypes   type2,
                                     QName*                       q2,
                                     SubstitutionGroupComparator* comparator)
{
    if (type1 == ContentSpecNode::Leaf &&
        type2 == ContentSpecNode::Leaf) {
        if (comparator->isEquivalentTo(q1, q2) || comparator->isEquivalentTo(q2, q1))
            return true;
    }
    else if (type1 == ContentSpecNode::Leaf) {
        return uriInWildcard(q1, q2->getURI(), type2, comparator);
    }
    else if (type2 == ContentSpecNode::Leaf) {
        return uriInWildcard(q2, q1->getURI(), type1, comparator);
    }
    else {
        return wildcardIntersect(type1, q1->getURI(), type2, q2->getURI());
    }
    return false;
}

bool XercesElementWildcard::uriInWildcard(QName*                       qname,
                                          unsigned int                 wildcard,
                                          ContentSpecNode::NodeTypes   wtype,
                                          SubstitutionGroupComparator* comparator)
{
    if ((wtype & 0x0f)== ContentSpecNode::Any) {
        return true;
    }
    else if ((wtype & 0x0f)== ContentSpecNode::Any_NS) {
        // substitution of "uri" satisfies "wtype:wildcard"
        return comparator->isAllowedByWildcard(qname, wildcard, false);
    }
    else if ((wtype & 0x0f)== ContentSpecNode::Any_Other) {
        // substitution of "uri" satisfies "wtype:wildcard"
        return comparator->isAllowedByWildcard(qname, wildcard, true);
    }

    return false;
}

bool XercesElementWildcard::wildcardIntersect(ContentSpecNode::NodeTypes t1,
                                              unsigned int               w1,
                                              ContentSpecNode::NodeTypes t2,
                                              unsigned int               w2)
{
    if (((t1 & 0x0f) == ContentSpecNode::Any) ||
        ((t2 & 0x0f) == ContentSpecNode::Any)) {
        // if either one is "##any", then intersects
        return true;
    }
    else if (((t1 & 0x0f) == ContentSpecNode::Any_NS) &&
             ((t2 & 0x0f) == ContentSpecNode::Any_NS) &&
             (w1 == w2)) {
        // if both are "some_namespace" and equal, then intersects
        return true;
    }
    else if (((t1 & 0x0f) == ContentSpecNode::Any_Other) &&
             ((t2 & 0x0f) == ContentSpecNode::Any_Other)) {
        // if both are "##other", and equal, then intersects
        return true;
    }
    else if (((((t1 & 0x0f) == ContentSpecNode::Any_NS) &&
               ((t2 & 0x0f) == ContentSpecNode::Any_Other)) ||
              (((t1 & 0x0f) == ContentSpecNode::Any_Other) &&
               ((t2 & 0x0f) == ContentSpecNode::Any_NS))) &&
             (w1 != w2)) {
        return true;
    }
    return false;
}

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/*
 * Copyright 2019 IBM International Business Machines Corp.
 *
 * 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.
 */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file target_types.H
 * @brief definitions for fapi2 target types
 */

#ifndef __FAPI2_TARGET_TYPES__
#define __FAPI2_TARGET_TYPES__
#include <stdint.h>

/// FAPI namespace
namespace fapi2
{
///
/// @enum fapi::TargetType
/// @brief Types, kinds, of targets
/// @note TYPE_NONE is used to represent empty/NULL targets in lists
/// or tables. TYPE_ALL is used to pass targets to methods which
/// can act generally on any type of target
///

/// Target Kind
enum TargetType : uint64_t
{
    TARGET_TYPE_NONE          = 0x0000000000000000, ///< No type
    TARGET_TYPE_SYSTEM        = 0x0000000000000001, ///< System type
    TARGET_TYPE_DIMM          = 0x0000000000000002, ///< DIMM type
    TARGET_TYPE_PROC_CHIP     = 0x0000000000000004, ///< Processor type
    TARGET_TYPE_MEMBUF_CHIP   = 0x0000000000000008, ///< Membuf type
    TARGET_TYPE_EX            = 0x0000000000000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
    TARGET_TYPE_MBA           = 0x0000000000000020, ///< MBA type
    TARGET_TYPE_MCS           = 0x0000000000000040, ///< MCS type
    TARGET_TYPE_XBUS          = 0x0000000000000080, ///< XBUS type
    TARGET_TYPE_ABUS          = 0x0000000000000100, ///< ABUS type
    TARGET_TYPE_L4            = 0x0000000000000200, ///< L4 type
    TARGET_TYPE_CORE          = 0x0000000000000400, ///< Core
    TARGET_TYPE_EQ            = 0x0000000000000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
    TARGET_TYPE_MCA           = 0x0000000000001000, ///< MCA type
    TARGET_TYPE_MCBIST        = 0x0000000000002000, ///< MCBIST type
    TARGET_TYPE_MI            = 0x0000000000004000, ///< MI Memory Interface (Cumulus)
    TARGET_TYPE_CAPP          = 0x0000000000008000, ///< CAPP target
    TARGET_TYPE_DMI           = 0x0000000000010000, ///< DMI type
    TARGET_TYPE_OBUS          = 0x0000000000020000, ///< OBUS type
    TARGET_TYPE_OBUS_BRICK    = 0x0000000000040000, ///< OBUS BRICK type
    TARGET_TYPE_SBE           = 0x0000000000080000, ///< SBE type
    TARGET_TYPE_PPE           = 0x0000000000100000, ///< PPE type
    TARGET_TYPE_PERV          = 0x0000000000200000, ///< Pervasive type
    TARGET_TYPE_PEC           = 0x0000000000400000, ///< PEC type
    TARGET_TYPE_PHB           = 0x0000000000800000, ///< PHB type
    TARGET_TYPE_MC            = 0x0000000001000000, ///< MC type
    TARGET_TYPE_OMI           = 0x0000000002000000, ///< OMI type
    TARGET_TYPE_OMIC          = 0x0000000004000000, ///< OMIC type
    TARGET_TYPE_MCC           = 0x0000000008000000, ///< MCC type
    TARGET_TYPE_OCMB_CHIP     = 0x0000000010000000, ///< OCMB type
    TARGET_TYPE_MEM_PORT      = 0x0000000020000000, ///< MEM_PORT type
    TARGET_TYPE_NMMU          = 0x0000000040000000, ///< NEST MMU type
#ifdef FAPI_2_Z
    TARGET_TYPE_SC_CHIP       = 0x0000000080000000, ///< Z SC type
#else
    TARGET_TYPE_RESERVED      = 0x0000000080000000, ///< Reserved for Cronus (Z)
#endif
    TARGET_TYPE_PAU           = 0x0000000100000000, ///< PAU type
    TARGET_TYPE_IOHS          = 0x0000000200000000, ///< IOHS type
    TARGET_TYPE_FC            = 0x0000000400000000, ///< Fused Core type
    TARGET_TYPE_PMIC          = 0x0000000800000000, ///< PMIC type
    TARGET_TYPE_PAUC          = 0x0000001000000000, ///< PAUC type
    TARGET_TYPE_MULTICAST     = 0x8000000000000000, ///< MULTICAST type
    TARGET_TYPE_ALL           = 0x7FFFFFFFFFFFFFFF, ///< Any/All types
    TARGET_TYPE_ALL_MC        = 0xFFFFFFFFFFFFFFFF, ///< Any/All types + Multicast

    // Compound target types
    TARGET_TYPE_CHIPS         = TARGET_TYPE_PROC_CHIP |
#ifdef FAPI_2_Z
                                TARGET_TYPE_SC_CHIP |
#endif
                                TARGET_TYPE_MEMBUF_CHIP |
                                TARGET_TYPE_OCMB_CHIP,

    TARGET_TYPE_CHIPLETS      = TARGET_TYPE_EX            |
                                TARGET_TYPE_MBA           |
                                TARGET_TYPE_MCS           |
                                TARGET_TYPE_XBUS          |
                                TARGET_TYPE_ABUS          |
                                TARGET_TYPE_L4            |
                                TARGET_TYPE_CORE          |
                                TARGET_TYPE_EQ            |
                                TARGET_TYPE_MCA           |
                                TARGET_TYPE_MCBIST        |
                                TARGET_TYPE_MI            |
                                TARGET_TYPE_DMI           |
                                TARGET_TYPE_OBUS          |
                                TARGET_TYPE_OBUS_BRICK    |
                                TARGET_TYPE_SBE           |
                                TARGET_TYPE_PPE           |
                                TARGET_TYPE_PERV          |
                                TARGET_TYPE_PEC           |
                                TARGET_TYPE_PHB           |
                                TARGET_TYPE_MC            |
                                TARGET_TYPE_OMI           |
                                TARGET_TYPE_OMIC          |
                                TARGET_TYPE_MCC           |
                                TARGET_TYPE_MEM_PORT      |
                                TARGET_TYPE_NMMU          |
                                TARGET_TYPE_PAU           |
                                TARGET_TYPE_IOHS          |
                                TARGET_TYPE_FC            |
                                TARGET_TYPE_PAUC,

    TARGET_TYPE_MULTICASTABLE = TARGET_TYPE_CORE   |
                                TARGET_TYPE_EQ     |
                                TARGET_TYPE_IOHS   |
                                TARGET_TYPE_MC     |
                                TARGET_TYPE_PAUC   |
                                TARGET_TYPE_PEC    |
                                TARGET_TYPE_PERV,

    // Mappings to target types found in the error xml files
    TARGET_TYPE_EX_CHIPLET    = TARGET_TYPE_EX,
    TARGET_TYPE_MBA_CHIPLET   = TARGET_TYPE_MBA,
    TARGET_TYPE_MCS_CHIPLET   = TARGET_TYPE_MCS,
    TARGET_TYPE_XBUS_ENDPOINT = TARGET_TYPE_XBUS,
    TARGET_TYPE_ABUS_ENDPOINT = TARGET_TYPE_ABUS,
#ifdef FAPI_2_Z
    // Z mappings
    TARGET_TYPE_EP_CHIP       = TARGET_TYPE_PROC_CHIP,
    TARGET_TYPE_XBUS0         = TARGET_TYPE_XBUS,
    TARGET_TYPE_XBUS1         = TARGET_TYPE_OBUS,
    TARGET_TYPE_NEST          = TARGET_TYPE_CAPP,
    TARGET_TYPE_PCIE          = TARGET_TYPE_PEC,
    TARGET_TYPE_GXA           = TARGET_TYPE_PHB,
#endif
};

///
/// Target filter 64-bit
/// Declare the enumeration size so that target.H will compile without chip specific filter.
/// When users want to use an enumeration value then they can include the chip specific
/// target_filters.H, which would have the enumerator list of values.
///
enum TargetFilter : uint64_t;

// attributeOverride tool requires x86.nfp compile
#ifndef CONTEXT_x86_nfp
/// @cond
constexpr TargetType operator|(TargetType x, TargetType y)
{
    return static_cast<TargetType>(static_cast<uint64_t>(x) |
                                   static_cast<uint64_t>(y));
}
#endif

template<uint64_t V>
class bitCount
{
    public:
        // Don't use enums, too hard to compare
        static const uint8_t count = bitCount < (V >> 1) >::count + (V & 1);
};

template<>
class bitCount<0>
{
    public:
        static const uint8_t count = 0;
};
/// @endcond

}

#endif
<commit_msg>additional target type added<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/*
 * Copyright 2020 IBM International Business Machines Corp.
 *
 * 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.
 */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file target_types.H
 * @brief definitions for fapi2 target types
 */

#ifndef __FAPI2_TARGET_TYPES__
#define __FAPI2_TARGET_TYPES__
#include <stdint.h>

/// FAPI namespace
namespace fapi2
{
///
/// @enum fapi::TargetType
/// @brief Types, kinds, of targets
/// @note TYPE_NONE is used to represent empty/NULL targets in lists
/// or tables. TYPE_ALL is used to pass targets to methods which
/// can act generally on any type of target
///

/// Target Kind
enum TargetType : uint64_t
{
    TARGET_TYPE_NONE          = 0x0000000000000000, ///< No type
    TARGET_TYPE_SYSTEM        = 0x0000000000000001, ///< System type
    TARGET_TYPE_DIMM          = 0x0000000000000002, ///< DIMM type
    TARGET_TYPE_PROC_CHIP     = 0x0000000000000004, ///< Processor type
    TARGET_TYPE_MEMBUF_CHIP   = 0x0000000000000008, ///< Membuf type
    TARGET_TYPE_EX            = 0x0000000000000010, ///< EX - 2x Core, L2, L3 - can be deconfigured
    TARGET_TYPE_MBA           = 0x0000000000000020, ///< MBA type
    TARGET_TYPE_MCS           = 0x0000000000000040, ///< MCS type
    TARGET_TYPE_XBUS          = 0x0000000000000080, ///< XBUS type
    TARGET_TYPE_ABUS          = 0x0000000000000100, ///< ABUS type
    TARGET_TYPE_L4            = 0x0000000000000200, ///< L4 type
    TARGET_TYPE_CORE          = 0x0000000000000400, ///< Core
    TARGET_TYPE_EQ            = 0x0000000000000800, ///< EQ - 4x core, 2x L2, 2x L3 - can be deconfigured
    TARGET_TYPE_MCA           = 0x0000000000001000, ///< MCA type
    TARGET_TYPE_MCBIST        = 0x0000000000002000, ///< MCBIST type
    TARGET_TYPE_MI            = 0x0000000000004000, ///< MI Memory Interface (Cumulus)
    TARGET_TYPE_CAPP          = 0x0000000000008000, ///< CAPP target
    TARGET_TYPE_DMI           = 0x0000000000010000, ///< DMI type
    TARGET_TYPE_OBUS          = 0x0000000000020000, ///< OBUS type
    TARGET_TYPE_OBUS_BRICK    = 0x0000000000040000, ///< OBUS BRICK type
    TARGET_TYPE_SBE           = 0x0000000000080000, ///< SBE type
    TARGET_TYPE_PPE           = 0x0000000000100000, ///< PPE type
    TARGET_TYPE_PERV          = 0x0000000000200000, ///< Pervasive type
    TARGET_TYPE_PEC           = 0x0000000000400000, ///< PEC type
    TARGET_TYPE_PHB           = 0x0000000000800000, ///< PHB type
    TARGET_TYPE_MC            = 0x0000000001000000, ///< MC type
    TARGET_TYPE_OMI           = 0x0000000002000000, ///< OMI type
    TARGET_TYPE_OMIC          = 0x0000000004000000, ///< OMIC type
    TARGET_TYPE_MCC           = 0x0000000008000000, ///< MCC type
    TARGET_TYPE_OCMB_CHIP     = 0x0000000010000000, ///< OCMB type
    TARGET_TYPE_MEM_PORT      = 0x0000000020000000, ///< MEM_PORT type
    TARGET_TYPE_NMMU          = 0x0000000040000000, ///< NEST MMU type
#ifdef FAPI_2_Z
    TARGET_TYPE_SC_CHIP       = 0x0000000080000000, ///< Z SC type
#else
    TARGET_TYPE_RESERVED      = 0x0000000080000000, ///< Reserved for Cronus (Z)
#endif
    TARGET_TYPE_PAU           = 0x0000000100000000, ///< PAU type
    TARGET_TYPE_IOHS          = 0x0000000200000000, ///< IOHS type
    TARGET_TYPE_FC            = 0x0000000400000000, ///< Fused Core type
    TARGET_TYPE_PMIC          = 0x0000000800000000, ///< PMIC type
    TARGET_TYPE_PAUC          = 0x0000001000000000, ///< PAUC type
    TARGET_TYPE_GENERICI2CSLAVE = 0x0000002000000000, ///< GENERICI2CSLAVE type
    TARGET_TYPE_MULTICAST     = 0x8000000000000000, ///< MULTICAST type
    TARGET_TYPE_ALL           = 0x7FFFFFFFFFFFFFFF, ///< Any/All types
    TARGET_TYPE_ALL_MC        = 0xFFFFFFFFFFFFFFFF, ///< Any/All types + Multicast

    // Compound target types
    TARGET_TYPE_CHIPS         = TARGET_TYPE_PROC_CHIP |
#ifdef FAPI_2_Z
                                TARGET_TYPE_SC_CHIP |
#endif
                                TARGET_TYPE_MEMBUF_CHIP |
                                TARGET_TYPE_OCMB_CHIP,

    TARGET_TYPE_CHIPLETS      = TARGET_TYPE_EX            |
                                TARGET_TYPE_MBA           |
                                TARGET_TYPE_MCS           |
                                TARGET_TYPE_XBUS          |
                                TARGET_TYPE_ABUS          |
                                TARGET_TYPE_L4            |
                                TARGET_TYPE_CORE          |
                                TARGET_TYPE_EQ            |
                                TARGET_TYPE_MCA           |
                                TARGET_TYPE_MCBIST        |
                                TARGET_TYPE_MI            |
                                TARGET_TYPE_DMI           |
                                TARGET_TYPE_OBUS          |
                                TARGET_TYPE_OBUS_BRICK    |
                                TARGET_TYPE_SBE           |
                                TARGET_TYPE_PPE           |
                                TARGET_TYPE_PERV          |
                                TARGET_TYPE_PEC           |
                                TARGET_TYPE_PHB           |
                                TARGET_TYPE_MC            |
                                TARGET_TYPE_OMI           |
                                TARGET_TYPE_OMIC          |
                                TARGET_TYPE_MCC           |
                                TARGET_TYPE_MEM_PORT      |
                                TARGET_TYPE_NMMU          |
                                TARGET_TYPE_PAU           |
                                TARGET_TYPE_IOHS          |
                                TARGET_TYPE_FC            |
                                TARGET_TYPE_PAUC,

    TARGET_TYPE_MULTICASTABLE = TARGET_TYPE_CORE   |
                                TARGET_TYPE_EQ     |
                                TARGET_TYPE_IOHS   |
                                TARGET_TYPE_MC     |
                                TARGET_TYPE_PAUC   |
                                TARGET_TYPE_PEC    |
                                TARGET_TYPE_PERV,

    // Mappings to target types found in the error xml files
    TARGET_TYPE_EX_CHIPLET    = TARGET_TYPE_EX,
    TARGET_TYPE_MBA_CHIPLET   = TARGET_TYPE_MBA,
    TARGET_TYPE_MCS_CHIPLET   = TARGET_TYPE_MCS,
    TARGET_TYPE_XBUS_ENDPOINT = TARGET_TYPE_XBUS,
    TARGET_TYPE_ABUS_ENDPOINT = TARGET_TYPE_ABUS,
#ifdef FAPI_2_Z
    // Z mappings
    TARGET_TYPE_EP_CHIP       = TARGET_TYPE_PROC_CHIP,
    TARGET_TYPE_XBUS0         = TARGET_TYPE_XBUS,
    TARGET_TYPE_XBUS1         = TARGET_TYPE_OBUS,
    TARGET_TYPE_NEST          = TARGET_TYPE_CAPP,
    TARGET_TYPE_PCIE          = TARGET_TYPE_PEC,
    TARGET_TYPE_GXA           = TARGET_TYPE_PHB,
#endif
};

///
/// Target filter 64-bit
/// Declare the enumeration size so that target.H will compile without chip specific filter.
/// When users want to use an enumeration value then they can include the chip specific
/// target_filters.H, which would have the enumerator list of values.
///
enum TargetFilter : uint64_t;

// attributeOverride tool requires x86.nfp compile
#ifndef CONTEXT_x86_nfp
/// @cond
constexpr TargetType operator|(TargetType x, TargetType y)
{
    return static_cast<TargetType>(static_cast<uint64_t>(x) |
                                   static_cast<uint64_t>(y));
}
#endif

template<uint64_t V>
class bitCount
{
    public:
        // Don't use enums, too hard to compare
        static const uint8_t count = bitCount < (V >> 1) >::count + (V & 1);
};

template<>
class bitCount<0>
{
    public:
        static const uint8_t count = 0;
};
/// @endcond

}

#endif
<|endoftext|>


<commit_before>/*
 Copyright (C)2010-2015 Paul Houx
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted.

  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.
*/

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/CameraUi.h"
#include "cinder/TriMesh.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class Picking3DApp : public App {
public:
	void setup() override;
	void update() override;
	void draw() override;

	void mouseMove( MouseEvent event ) override;

	bool performPicking( vec3 *pickedPoint, vec3 *pickedNormal );
	void drawCube( const AxisAlignedBox &bounds, const Color &color );

private:
	TriMeshRef			mTriMesh;		//! The 3D mesh.
	AxisAlignedBox	mObjectBounds; 	//! The object space bounding box of the mesh.
	mat4				mTransform;		//! Transformations (translate, rotate, scale) of the mesh.

	//! By caching a 3D model and its shader on the GPU, we can draw it faster.
	gl::BatchRef		mWireCube;
	gl::BatchRef		mWirePlane;
	gl::BatchRef		mMesh;

	CameraPersp			mCamera;
	CameraUi			mCamUi;

	ivec2				mMousePos;		//! Keep track of the mouse.
};

void Picking3DApp::setup()
{
	// Create the mesh.
	mTriMesh = TriMesh::create( geom::Teapot().subdivisions( 6 ) );

	// Get the object space bounding box of the model, for fast intersection testing.
	mObjectBounds = mTriMesh->calcBoundingBox();

	// Set up the camera.
	mCamera.lookAt( vec3( 2.0f, 3.0f, 1.0f ), vec3( 0 ) );
	mCamera.setPerspective( 40.0f, getWindowAspectRatio(), 0.01f, 100.0f );
	mCamUi = CameraUi( &mCamera, getWindow() );

	// Create batches that render fast.
	auto lambertShader = gl::getStockShader( gl::ShaderDef().color().lambert() );
	auto colorShader = gl::getStockShader( gl::ShaderDef().color() );

	mMesh = gl::Batch::create( *mTriMesh, lambertShader );
	mWirePlane = gl::Batch::create( geom::WirePlane().size( vec2( 10 ) ).subdivisions( ivec2( 10 ) ), colorShader );
	mWireCube = gl::Batch::create( geom::WireCube(), colorShader );
}

void Picking3DApp::update()
{
	// Animate our mesh.
	mTransform = mat4( 1.0f );
	mTransform *= rotate( sin( (float) getElapsedSeconds() * 3.0f ) * 0.08f, vec3( 1, 0, 0 ) );
	mTransform *= rotate( (float) getElapsedSeconds() * 0.1f, vec3( 0, 1, 0 ) );
	mTransform *= rotate( sin( (float) getElapsedSeconds() * 4.3f ) * 0.09f, vec3( 0, 0, 1 ) );
}

void Picking3DApp::draw()
{
	// Gray background.
	gl::clear( Color::gray( 0.5f ) );

	// Set up the camera.
	gl::ScopedMatrices push;
	gl::setMatrices( mCamera );

	// Enable depth buffer.
	gl::ScopedDepth depth( true, true );

	// Draw the grid on the floor.
	{
		gl::ScopedColor color( Color::gray( 0.2f ) );
		mWirePlane->draw();
	}

	// Draw the mesh.
	{
		gl::ScopedColor color( Color::white() );

		gl::ScopedModelMatrix model;
		gl::multModelMatrix( mTransform );

		mMesh->draw();
	}

	// Perform 3D picking now, so we can draw the result as a vector.
	vec3 pickedPoint, pickedNormal;
	if( performPicking( &pickedPoint, &pickedNormal ) ) {
		gl::ScopedColor color( Color( 0, 1, 0 ) );

		// Draw an arrow to the picked point along its normal.
		gl::ScopedGlslProg shader( gl::getStockShader( gl::ShaderDef().color().lambert() ) );
		gl::drawVector( pickedPoint + pickedNormal, pickedPoint );
	}
}

void Picking3DApp::mouseMove( MouseEvent event )
{
	// Keep track of the mouse.
	mMousePos = event.getPos();
}

bool Picking3DApp::performPicking( vec3 *pickedPoint, vec3 *pickedNormal )
{
	// Generate a ray from the camera into our world. Note that we have to
	// flip the vertical coordinate.
	float u = mMousePos.x / (float) getWindowWidth();
	float v = mMousePos.y / (float) getWindowHeight();
	Ray ray = mCamera.generateRay( u, 1.0f - v, mCamera.getAspectRatio() );

	// The coordinates of the bounding box are in object space, not world space,
	// so if the model was translated, rotated or scaled, the bounding box would not
	// reflect that. One solution would be to pass the transformation to the calcBoundingBox() function:
	AxisAlignedBox worldBoundsExact = mTriMesh->calcBoundingBox( mTransform ); // slow

	// But if you already have an object space bounding box, it's much faster to
	// approximate the world space bounding box like this:
	AxisAlignedBox worldBoundsApprox = mObjectBounds.transformed( mTransform ); // fast

	// Draw the object space bounding box in yellow. It will not animate,
	// because animation is done in world space.
	drawCube( mObjectBounds, Color( 1, 1, 0 ) );

	// Draw the exact bounding box in orange.
	drawCube( worldBoundsExact, Color( 1, 0.5f, 0 ) );

	// Draw the approximated bounding box in cyan.
	drawCube( worldBoundsApprox, Color( 0, 1, 1 ) );

	// Perform fast detection first - test against the bounding box itself.
	if( !worldBoundsExact.intersects( ray ) )
		return false;

	// Set initial distance to something far, far away.
	float result = FLT_MAX;

	// Traverse triangle list and find the closest intersecting triangle.
	const size_t polycount = mTriMesh->getNumTriangles();

	float distance = 0.0f;
	for( size_t i = 0; i < polycount; ++i ) {
		// Get a single triangle from the mesh.
		vec3 v0, v1, v2;
		mTriMesh->getTriangleVertices( i, &v0, &v1, &v2 );

		// Transform triangle to world space.
		v0 = vec3( mTransform * vec4( v0, 1.0 ) );
		v1 = vec3( mTransform * vec4( v1, 1.0 ) );
		v2 = vec3( mTransform * vec4( v2, 1.0 ) );

		// Test to see if the ray intersects this triangle.
		if( ray.calcTriangleIntersection( v0, v1, v2, &distance ) ) {
			// Keep the result if it's closer than any intersection we've had so far.
			if( distance < result ) {
				result = distance;

				// Assuming this is the closest triangle, we'll calculate our normal
				// while we've got all the points handy.
				*pickedNormal = normalize( cross( v1 - v0, v2 - v0 ) );
			}
		}
	}

	// Did we have a hit?
	if( distance > 0 ) {
		// Calculate the exact position of the hit.
		*pickedPoint = ray.calcPosition( result );

		return true;
	}
	else
		return false;
}

void Picking3DApp::drawCube( const AxisAlignedBox &bounds, const Color & color )
{
	gl::ScopedColor clr( color );
	gl::ScopedModelMatrix model;

	gl::multModelMatrix( glm::translate( bounds.getCenter() ) * glm::scale( bounds.getSize() ) );
	mWireCube->draw();
}

CINDER_APP( Picking3DApp, RendererGl( RendererGl::Options().msaa( 8 ) ) )<commit_msg>minor whitespace improvements to sample<commit_after>/*
 Copyright (C)2010-2015 Paul Houx
 All rights reserved.

 Redistribution and use in source and binary forms, with or without modification, are permitted.

  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.
*/

#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/CameraUi.h"
#include "cinder/TriMesh.h"

using namespace ci;
using namespace ci::app;
using namespace std;

class Picking3DApp : public App {
public:
	void setup() override;
	void update() override;
	void draw() override;

	void mouseMove( MouseEvent event ) override;

	bool performPicking( vec3 *pickedPoint, vec3 *pickedNormal );
	void drawCube( const AxisAlignedBox &bounds, const Color &color );

private:
	TriMeshRef			mTriMesh;		//! The 3D mesh.
	AxisAlignedBox		mObjectBounds; 	//! The object space bounding box of the mesh.
	mat4				mTransform;		//! Transformations (translate, rotate, scale) of the mesh.

	//! By caching a 3D model and its shader on the GPU, we can draw it faster.
	gl::BatchRef		mWireCube;
	gl::BatchRef		mWirePlane;
	gl::BatchRef		mMesh;

	CameraPersp			mCamera;
	CameraUi			mCamUi;

	ivec2				mMousePos;		//! Keep track of the mouse.
};

void Picking3DApp::setup()
{
	// Create the mesh.
	mTriMesh = TriMesh::create( geom::Teapot().subdivisions( 6 ) );

	// Get the object space bounding box of the model, for fast intersection testing.
	mObjectBounds = mTriMesh->calcBoundingBox();

	// Set up the camera.
	mCamera.lookAt( vec3( 2.0f, 3.0f, 1.0f ), vec3( 0 ) );
	mCamera.setPerspective( 40.0f, getWindowAspectRatio(), 0.01f, 100.0f );
	mCamUi = CameraUi( &mCamera, getWindow() );

	// Create batches that render fast.
	auto lambertShader = gl::getStockShader( gl::ShaderDef().color().lambert() );
	auto colorShader = gl::getStockShader( gl::ShaderDef().color() );

	mMesh = gl::Batch::create( *mTriMesh, lambertShader );
	mWirePlane = gl::Batch::create( geom::WirePlane().size( vec2( 10 ) ).subdivisions( ivec2( 10 ) ), colorShader );
	mWireCube = gl::Batch::create( geom::WireCube(), colorShader );
}

void Picking3DApp::update()
{
	// Animate our mesh.
	mTransform = mat4( 1.0f );
	mTransform *= rotate( sin( (float) getElapsedSeconds() * 3.0f ) * 0.08f, vec3( 1, 0, 0 ) );
	mTransform *= rotate( (float) getElapsedSeconds() * 0.1f, vec3( 0, 1, 0 ) );
	mTransform *= rotate( sin( (float) getElapsedSeconds() * 4.3f ) * 0.09f, vec3( 0, 0, 1 ) );
}

void Picking3DApp::draw()
{
	// Gray background.
	gl::clear( Color::gray( 0.5f ) );

	// Set up the camera.
	gl::ScopedMatrices push;
	gl::setMatrices( mCamera );

	// Enable depth buffer.
	gl::ScopedDepth depth( true, true );

	// Draw the grid on the floor.
	{
		gl::ScopedColor color( Color::gray( 0.2f ) );
		mWirePlane->draw();
	}

	// Draw the mesh.
	{
		gl::ScopedColor color( Color::white() );

		gl::ScopedModelMatrix model;
		gl::multModelMatrix( mTransform );

		mMesh->draw();
	}

	// Perform 3D picking now, so we can draw the result as a vector.
	vec3 pickedPoint, pickedNormal;
	if( performPicking( &pickedPoint, &pickedNormal ) ) {
		gl::ScopedColor color( Color( 0, 1, 0 ) );

		// Draw an arrow to the picked point along its normal.
		gl::ScopedGlslProg shader( gl::getStockShader( gl::ShaderDef().color().lambert() ) );
		gl::drawVector( pickedPoint + pickedNormal, pickedPoint );
	}
}

void Picking3DApp::mouseMove( MouseEvent event )
{
	// Keep track of the mouse.
	mMousePos = event.getPos();
}

bool Picking3DApp::performPicking( vec3 *pickedPoint, vec3 *pickedNormal )
{
	// Generate a ray from the camera into our world. Note that we have to
	// flip the vertical coordinate.
	float u = mMousePos.x / (float) getWindowWidth();
	float v = mMousePos.y / (float) getWindowHeight();
	Ray ray = mCamera.generateRay( u, 1.0f - v, mCamera.getAspectRatio() );

	// The coordinates of the bounding box are in object space, not world space,
	// so if the model was translated, rotated or scaled, the bounding box would not
	// reflect that. One solution would be to pass the transformation to the calcBoundingBox() function:
	AxisAlignedBox worldBoundsExact = mTriMesh->calcBoundingBox( mTransform ); // slow

	// But if you already have an object space bounding box, it's much faster to
	// approximate the world space bounding box like this:
	AxisAlignedBox worldBoundsApprox = mObjectBounds.transformed( mTransform ); // fast

	// Draw the object space bounding box in yellow. It will not animate,
	// because animation is done in world space.
	drawCube( mObjectBounds, Color( 1, 1, 0 ) );

	// Draw the exact bounding box in orange.
	drawCube( worldBoundsExact, Color( 1, 0.5f, 0 ) );

	// Draw the approximated bounding box in cyan.
	drawCube( worldBoundsApprox, Color( 0, 1, 1 ) );

	// Perform fast detection first - test against the bounding box itself.
	if( ! worldBoundsExact.intersects( ray ) )
		return false;

	// Set initial distance to something far, far away.
	float result = FLT_MAX;

	// Traverse triangle list and find the closest intersecting triangle.
	const size_t polycount = mTriMesh->getNumTriangles();

	float distance = 0.0f;
	for( size_t i = 0; i < polycount; ++i ) {
		// Get a single triangle from the mesh.
		vec3 v0, v1, v2;
		mTriMesh->getTriangleVertices( i, &v0, &v1, &v2 );

		// Transform triangle to world space.
		v0 = vec3( mTransform * vec4( v0, 1.0 ) );
		v1 = vec3( mTransform * vec4( v1, 1.0 ) );
		v2 = vec3( mTransform * vec4( v2, 1.0 ) );

		// Test to see if the ray intersects this triangle.
		if( ray.calcTriangleIntersection( v0, v1, v2, &distance ) ) {
			// Keep the result if it's closer than any intersection we've had so far.
			if( distance < result ) {
				result = distance;

				// Assuming this is the closest triangle, we'll calculate our normal
				// while we've got all the points handy.
				*pickedNormal = normalize( cross( v1 - v0, v2 - v0 ) );
			}
		}
	}

	// Did we have a hit?
	if( distance > 0 ) {
		// Calculate the exact position of the hit.
		*pickedPoint = ray.calcPosition( result );

		return true;
	}
	else
		return false;
}

void Picking3DApp::drawCube( const AxisAlignedBox &bounds, const Color & color )
{
	gl::ScopedColor clr( color );
	gl::ScopedModelMatrix model;

	gl::multModelMatrix( glm::translate( bounds.getCenter() ) * glm::scale( bounds.getSize() ) );
	mWireCube->draw();
}

CINDER_APP( Picking3DApp, RendererGl( RendererGl::Options().msaa( 8 ) ) )<|endoftext|>


<commit_before>//
// Copyright (c) 2016, Andre Gaschler
// 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.
//
// 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.
//

#include <iostream>
#include <rl/math/Array.h>
#include <rl/math/Spline.h>

void printPoly(const rl::math::Polynomial<rl::math::ArrayX>& p)
{
	for (int n = p.degree(); n >= 0; --n)
	{
		if (p.coefficient(n).matrix().squaredNorm() != 0)
		{
			std::cout << p.coefficient(n) << "*x^" << n << " ";
		}
	}

	std::cout << std::endl;
}

bool testPolynomialTranslation(const rl::math::Polynomial<rl::math::ArrayX>& p)
{
	rl::math::Real eps = 1e-6;
	rl::math::Real translation = 0.2 + (p.degree() / 3);
	rl::math::Polynomial<rl::math::ArrayX> q = p.translatedX(translation);
	printPoly(p);
	printPoly(q);
	bool ok = true;

	for (rl::math::Real x = 0; x < 1; x += 0.1)
	{
		if ((p(x) - q(x - translation)).matrix().squaredNorm() > eps)
		{
			ok = false;
		}
	}

	if (!ok)
	{
		std::cerr << "testPolynomialTranslation: at degree " << p.degree() << " a difference was detected." << std::endl;
	}

	return ok;
}

int
main(int argc, char** argv)
{
	bool ok = true;

	for (std::size_t degree = 5; degree < 15; ++degree)
	{
		rl::math::Polynomial<rl::math::ArrayX> p(degree);
		p.upper() = 1;

		for (std::size_t n = 0; n < p.degree() + 1; ++n)
		{
			p.coefficient(n) = rl::math::ArrayX::Zero(1);
		}

		p.coefficient(degree) = rl::math::ArrayX::Constant(1, 1.7);
		p.coefficient(degree / 2) = rl::math::ArrayX::Constant(1, -2.5);
		p.coefficient(degree / 3) = rl::math::ArrayX::Constant(1, 1.5);
		ok &= testPolynomialTranslation(p);

		p.coefficient(degree - 1) = rl::math::ArrayX::Constant(1, -0.5);
		ok &= testPolynomialTranslation(p);
	}

	if (ok)
	{
		std::cout << "rlSplineTranslationTest: Verify Polynomial::translatedX done." << std::endl;
		return EXIT_SUCCESS;
	}
	else
	{
		std::cerr << "rlSplineTranslationTest: Polynomial::translatedX is wrong." << std::endl;
		return EXIT_FAILURE;
	}
}
<commit_msg>Update float comparison in rlSplineTranslationTest<commit_after>//
// Copyright (c) 2016, Andre Gaschler
// 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.
//
// 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.
//

#include <iostream>
#include <rl/math/Array.h>
#include <rl/math/Spline.h>

void printPoly(const rl::math::Polynomial<rl::math::ArrayX>& p)
{
	for (int n = p.degree(); n >= 0; --n)
	{
		if (p.coefficient(n).matrix().squaredNorm() > 0)
		{
			std::cout << p.coefficient(n) << "*x^" << n << " ";
		}
	}

	std::cout << std::endl;
}

bool testPolynomialTranslation(const rl::math::Polynomial<rl::math::ArrayX>& p)
{
	rl::math::Real eps = 1e-6;
	rl::math::Real translation = 0.2 + (p.degree() / 3);
	rl::math::Polynomial<rl::math::ArrayX> q = p.translatedX(translation);
	printPoly(p);
	printPoly(q);
	bool ok = true;

	for (rl::math::Real x = 0; x < 1; x += 0.1)
	{
		if ((p(x) - q(x - translation)).matrix().squaredNorm() > eps)
		{
			ok = false;
		}
	}

	if (!ok)
	{
		std::cerr << "testPolynomialTranslation: at degree " << p.degree() << " a difference was detected." << std::endl;
	}

	return ok;
}

int
main(int argc, char** argv)
{
	bool ok = true;

	for (std::size_t degree = 5; degree < 15; ++degree)
	{
		rl::math::Polynomial<rl::math::ArrayX> p(degree);
		p.upper() = 1;

		for (std::size_t n = 0; n < p.degree() + 1; ++n)
		{
			p.coefficient(n) = rl::math::ArrayX::Zero(1);
		}

		p.coefficient(degree) = rl::math::ArrayX::Constant(1, 1.7);
		p.coefficient(degree / 2) = rl::math::ArrayX::Constant(1, -2.5);
		p.coefficient(degree / 3) = rl::math::ArrayX::Constant(1, 1.5);
		ok &= testPolynomialTranslation(p);

		p.coefficient(degree - 1) = rl::math::ArrayX::Constant(1, -0.5);
		ok &= testPolynomialTranslation(p);
	}

	if (ok)
	{
		std::cout << "rlSplineTranslationTest: Verify Polynomial::translatedX done." << std::endl;
		return EXIT_SUCCESS;
	}
	else
	{
		std::cerr << "rlSplineTranslationTest: Polynomial::translatedX is wrong." << std::endl;
		return EXIT_FAILURE;
	}
}
<|endoftext|>