<commit_before>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file meta.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__UTIL__META_HPP
#define FL__UTIL__META_HPP

#include <Eigen/Dense>

#include <memory>

#include <fl/util/traits.hpp>

namespace fl
{

/**
 * \ingroup meta
 *
 * \tparam Sizes    Variadic argument containing a list of sizes. Each size
 *                  is a result of a constexpr or a const of a signed integral
 *                  type. Unknown sizes are represented by -1 or Eigen::Dynamic.
 *
 *
 * Joins the sizes within the \c Sizes argument list if all sizes are
 * non-dynamic. That is, all sizes are greater -1 (\c Eigen::Dynamic). If one of
 * the passed sizes is \c Eigen::Dynamic, the total size collapses to
 * \c Eigen::Dynamic.
 */
template <int... Sizes> struct JoinSizes;

/**
 * \internal
 * \ingroup meta
 * \copydoc JoinSizes
 *
 * \tparam Head     Head of the \c Sizes list of the previous recursive call
 *
 * Variadic counting recursion
 */
template <int Head, int... Sizes> struct JoinSizes<Head, Sizes...>
{
    enum : signed int
    {
        Size = IsFixed<Head>() && IsFixed<JoinSizes<Sizes...>::Size>()
                   ? Head + JoinSizes<Sizes...>::Size
                   : Eigen::Dynamic
    };
};

/**
 * \internal
 * \ingroup meta
 *
 * Terminal specialization of JoinSizes<...>
 */
template <> struct JoinSizes<> { enum: signed int { Size = 0 }; } ;

/**
 * \ingroup meta
 *
 * \brief Function form of JoinSizes for two sizes
 */
inline constexpr int join_sizes(int a, int b)
{
    return (a > Eigen::Dynamic && b > Eigen::Dynamic) ? a + b : Eigen::Dynamic;
}

/**
 * \ingroup meta
 *
 * Computes the product of LocalSize times Factor. If one of the parameters is
 * set to Eigen::Dynamic, the factor size will collapse to Eigen::Dynbamic as
 * well.
 */
template <int ... Sizes> struct ExpandSizes;

/**
 * \internal
 * \ingroup meta
 */
template <int Head, int... Sizes> struct ExpandSizes<Head, Sizes...>
{
    enum: signed int
    {
        Size = IsFixed<Head>() && IsFixed<ExpandSizes<Sizes...>::Size>()
                   ? Head * ExpandSizes<Sizes...>::Size
                   : Eigen::Dynamic
    };
};

/**
 * \internal
 * \ingroup meta
 *
 * Terminal specialization of ExpandSizes<...>
 */
template <> struct ExpandSizes<> { enum: signed int { Size = 1 }; } ;

/**
 * \ingroup meta
 *
 * Provides access to the the first type element in the specified variadic list
 */
template <typename...T> struct FirstTypeIn;

/**
 * \internal
 * \ingroup meta
 *
 * Implementation of FirstTypeIn
 */
template <typename First, typename...T>
struct FirstTypeIn<First, T...>
{
    typedef First Type;
};

/**
 * \ingroup meta
 *
 * Represents a sequence of indices IndexSequence<0, 1, 2, 3, ...>
 *
 * This is particularly useful to expand tuples
 *
 * \tparam Indices  List of indices starting from 0
 */
template <int ... Indices> struct IndexSequence
{
    enum { Size = sizeof...(Indices) };
};

/**
 * \ingroup meta
 *
 * Creates an IndexSequence<0, 1, 2, ...> for a specified size.
 */
template <int Size, int ... Indices>
struct CreateIndexSequence
    : CreateIndexSequence<Size - 1, Size - 1, Indices...>
{ };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal specialization CreateIndexSequence
 */
template <int ... Indices>
struct CreateIndexSequence<0, Indices...>
    : IndexSequence<Indices...>
{ };

/**
 * \ingroup meta
 *
 * Meta type defined in terms of a sequence of types
 */
template <typename ... T>
struct TypeSequence
{
    enum : signed int { Size = sizeof...(T) };
};

/**
 * \internal
 * \ingroup meta
 *
 * Empty TypeSequence
 */
template <> struct TypeSequence<>
{
    enum : signed int { Size = Eigen::Dynamic };
};

/**
 * \ingroup meta
 *
 * Creates a \c TypeSequence<T...> by expanding the specified \c Type \c Count
 * times.
 */
template <int Count, typename Type, typename...T>
struct CreateTypeSequence
    : CreateTypeSequence<Count - 1, Type, Type, T...>
{ };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal type of CreateTypeSequence
 */
template <typename Type, typename...T>
struct CreateTypeSequence<1, Type, T...>
    : TypeSequence<Type, T...>
{ };

/**
 * \ingroup meta
 *
 * Creates an empty \c TypeSequence<> for a \c Count = Eigen::Dynamic
 */
template <typename Type>
struct CreateTypeSequence<Eigen::Dynamic, Type>
  : TypeSequence<>
{ };

template <typename Model, typename ParameterProcess>
struct AdaptiveModel { };

/**
 * \ingroup meta
 *
 * Same as CreateTypeSequence, however with a reversed parameter order. This is
 * an attempt to make the use of \c CreateTypeSequence more natural. It also
 * allows dynamic sizes if needed.
 */
template <typename Type, int Count = Eigen::Dynamic>
struct MultipleOf
    : CreateTypeSequence<Count, Type>
{
    MultipleOf(std::shared_ptr<Type> instance, int instance_count = Count)
        : instance_(instance),
          count_(instance_count)
    { }

    std::shared_ptr<Type> instance() const { return instance_; }
    int count() const { return count_; }

    std::shared_ptr<Type> instance_;
    int count_;
};

/**
 * \internal
 * \ingroup meta
 * \todo fix
 *
 * Creates an empty TypeSequence for dynamic count
 */
//template <typename Type>
//struct MultipleOf<Type, Eigen::Dynamic>
//    : CreateTypeSequence<Eigen::Dynamic, Type>
//{ };

/**
 * \c Join represents a meta operator taking an argument pack which should be
 * unified in a specific way. The operator is defined by the following axioms
 *
 * - Pack of Join<P1, P2, ...>: {P1, P2, ...}
 * - Positive pack:             sizeof...(T) > 0 for Join<T...>
 * - Nesting:                   Join<P1, Join<P2, P3>> = {P1, P2, P3}
 * - Comm.                      Join<P1, Join<P2, P3>> = Join<Join<P1, P2>, P3>
 * - MultipleOf operator:       Join<MultipleOf<P, #>>
 *
 * \ingroup meta
 */
template <typename...T> struct Join;

/**
 * \internal
 * \ingroup meta
 *
 * Collapes the argument pack of the Join operator into Model<T...> of ay given
 * Join<...> operator.
 */
template <typename...T> struct CollapseJoin;

/**
 * \internal
 * \ingroup meta
 *
 * CollapseJoin specialization which expands the type sequence by the Head
 * element assuming Head is neither a Join<...> nor a MultipleOf<P, #> operator.
 */
template <
    typename...S,
    typename Head,
    typename...T,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,                 // Final model type
           TypeSequence<S...>,      // Type sequence holding the pack expansion
           Head,                    // Current non-operator pack head element
           T...>                    // Remaining Tail
  : CollapseJoin<
        Model<>,                    // Final model type
        TypeSequence<Head, S...>,   // updated type sequence
        T...>                       // Remaining Tail
{ };

/**
 * \internal
 * \ingroup meta
 *
 * CollapseJoin specialization which unifies a Join<...> pack Head into the
 * outer Join pack, i.e.
 *
 * Join<T1..., Join<T2...>, T3 > = Join<T1..., T2..., T3...>
 */
template <
    typename...S,
    typename...T,
    typename...U,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,                 // Final model type
           TypeSequence<S...>,      // Type sequence holding the pack expansion
           Join<T...>,              // Current pack head element
           U...>                    // Remaining Tail
  : CollapseJoin<
        Model<>,                    // Final model type
        TypeSequence<S...>,         // Type sequence holding the pack expansion
        T...,                       // Extracted pack from inner Join operator
        U...>                       // Remaining Tail
{ };

/**
 * \internal
 * \ingroup meta
 *
 * CollapseJoin specialization which translates a MultipleOf<P,#> operator,
 * at the head of the pack, into Model<MultipleOf<P, #>>, i.e
 *
 * Join<T1..., MultipleOf<P, 10>, T2...> =
 * Join<T1..., Model<MultipleOf<P, 10>>, T2...>.
 */
template <
    typename...S,
    typename...T,
    typename U,
    int Count,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,                 // Final model type
           TypeSequence<S...>,      // Type sequence holding the pack expansion
           MultipleOf<U, Count>,    // Current pack head element
           T...>                    // Remaining Join pack, the tail
  : CollapseJoin<
        Model<>,                    // Final model type
        TypeSequence<S...>,         // Type sequence holding the pack expansion
        Model<MultipleOf<U, Count>>,// Redefine head in terms of Model<>
        T...>                       // Remaining Tail
{ };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal case of Join operator collapsing. The final result of Join<T...>
 * is Model<U...> where U are all the expanded non operator types.
 */
template <
    typename...S,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,
           TypeSequence<S...>>
{
    /**
     * \brief Final type outcome of the Join Operator
     */
    typedef Model<S...> Type;

    static_assert(sizeof...(S) > 1,
                  "Join<A, B, ...> operator must take 2 or more operands");
};

/**
 * \internal
 * \ingroup meta
 *
 * Terminal case of Join operator collapsing for a Join of the form
 * Join<MultipleOf<P, #>> resulting in Model<MultipleOf<P, #>>
 */
template <
    typename M,
    int Count,
    template <typename...> class Model
>
struct CollapseJoin<Model<>, TypeSequence<Model<MultipleOf<M, Count>>>>
{
    typedef Model<MultipleOf<M, Count>> Type;

    static_assert(Count > 0 || Count == -1,
                  "Cannot expand Join<MultipleOf<M, Count>> operator on M. "
                  "Count must be positive or set to -1 for the dynamic size "
                  "case.");
};

/**
 * \ingroup meta
 * Represents any number of available options as defined in #FilterOptions
 */
template <int T> struct Options { enum : signed int { Value = T }; };

/**
 * \ingroup meta
 * Combines multiple options into one. This allows to specify the options
 * listed in an arbitrary number
 */
template <int ... T> struct CombineOptions;

/**
 * \internal
 * \ingroup meta
 *
 * Combines the first option within the option pack with the previous one.
 */
template <int Value, int H, int ... T>
struct CombineOptions<Value, H, T...> : CombineOptions<Value | H, T...> { };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal case CombineOptions
 */
template <int Value>
struct CombineOptions<Value> { typedef fl::Options<Value> Options; };

/**
 * \internal
 * \ingroup meta
 *
 * No Option case
 */
template <>
struct CombineOptions<> { typedef fl::Options<NoOptions> Options; };

}

#endif

<commit_msg>MultipleOf: universal type deduction and perfect forwarding instead of shared_ptr<commit_after>/*
 * This is part of the FL library, a C++ Bayesian filtering library
 * (https://github.com/filtering-library)
 *
 * Copyright (c) 2014 Jan Issac (jan.issac@gmail.com)
 * Copyright (c) 2014 Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *
 * Max-Planck Institute for Intelligent Systems, AMD Lab
 * University of Southern California, CLMC Lab
 *
 * This Source Code Form is subject to the terms of the MIT License (MIT).
 * A copy of the license can be found in the LICENSE file distributed with this
 * source code.
 */

/**
 * \file meta.hpp
 * \date October 2014
 * \author Jan Issac (jan.issac@gmail.com)
 */

#ifndef FL__UTIL__META_HPP
#define FL__UTIL__META_HPP

#include <Eigen/Dense>

#include <memory>

#include <fl/util/traits.hpp>

namespace fl
{

/**
 * \ingroup meta
 *
 * \tparam Sizes    Variadic argument containing a list of sizes. Each size
 *                  is a result of a constexpr or a const of a signed integral
 *                  type. Unknown sizes are represented by -1 or Eigen::Dynamic.
 *
 *
 * Joins the sizes within the \c Sizes argument list if all sizes are
 * non-dynamic. That is, all sizes are greater -1 (\c Eigen::Dynamic). If one of
 * the passed sizes is \c Eigen::Dynamic, the total size collapses to
 * \c Eigen::Dynamic.
 */
template <int... Sizes> struct JoinSizes;

/**
 * \internal
 * \ingroup meta
 * \copydoc JoinSizes
 *
 * \tparam Head     Head of the \c Sizes list of the previous recursive call
 *
 * Variadic counting recursion
 */
template <int Head, int... Sizes> struct JoinSizes<Head, Sizes...>
{
    enum : signed int
    {
        Size = IsFixed<Head>() && IsFixed<JoinSizes<Sizes...>::Size>()
                   ? Head + JoinSizes<Sizes...>::Size
                   : Eigen::Dynamic
    };
};

/**
 * \internal
 * \ingroup meta
 *
 * Terminal specialization of JoinSizes<...>
 */
template <> struct JoinSizes<> { enum: signed int { Size = 0 }; } ;

/**
 * \ingroup meta
 *
 * \brief Function form of JoinSizes for two sizes
 */
inline constexpr int join_sizes(int a, int b)
{
    return (a > Eigen::Dynamic && b > Eigen::Dynamic) ? a + b : Eigen::Dynamic;
}

/**
 * \ingroup meta
 *
 * Computes the product of LocalSize times Factor. If one of the parameters is
 * set to Eigen::Dynamic, the factor size will collapse to Eigen::Dynbamic as
 * well.
 */
template <int ... Sizes> struct ExpandSizes;

/**
 * \internal
 * \ingroup meta
 */
template <int Head, int... Sizes> struct ExpandSizes<Head, Sizes...>
{
    enum: signed int
    {
        Size = IsFixed<Head>() && IsFixed<ExpandSizes<Sizes...>::Size>()
                   ? Head * ExpandSizes<Sizes...>::Size
                   : Eigen::Dynamic
    };
};

/**
 * \internal
 * \ingroup meta
 *
 * Terminal specialization of ExpandSizes<...>
 */
template <> struct ExpandSizes<> { enum: signed int { Size = 1 }; } ;

/**
 * \ingroup meta
 *
 * Provides access to the the first type element in the specified variadic list
 */
template <typename...T> struct FirstTypeIn;

/**
 * \internal
 * \ingroup meta
 *
 * Implementation of FirstTypeIn
 */
template <typename First, typename...T>
struct FirstTypeIn<First, T...>
{
    typedef First Type;
};

/**
 * \ingroup meta
 *
 * Represents a sequence of indices IndexSequence<0, 1, 2, 3, ...>
 *
 * This is particularly useful to expand tuples
 *
 * \tparam Indices  List of indices starting from 0
 */
template <int ... Indices> struct IndexSequence
{
    enum { Size = sizeof...(Indices) };
};

/**
 * \ingroup meta
 *
 * Creates an IndexSequence<0, 1, 2, ...> for a specified size.
 */
template <int Size, int ... Indices>
struct CreateIndexSequence
    : CreateIndexSequence<Size - 1, Size - 1, Indices...>
{ };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal specialization CreateIndexSequence
 */
template <int ... Indices>
struct CreateIndexSequence<0, Indices...>
    : IndexSequence<Indices...>
{ };

/**
 * \ingroup meta
 *
 * Meta type defined in terms of a sequence of types
 */
template <typename ... T>
struct TypeSequence
{
    enum : signed int { Size = sizeof...(T) };
};

/**
 * \internal
 * \ingroup meta
 *
 * Empty TypeSequence
 */
template <> struct TypeSequence<>
{
    enum : signed int { Size = Eigen::Dynamic };
};

/**
 * \ingroup meta
 *
 * Creates a \c TypeSequence<T...> by expanding the specified \c Type \c Count
 * times.
 */
template <int Count, typename Type, typename...T>
struct CreateTypeSequence
    : CreateTypeSequence<Count - 1, Type, Type, T...>
{ };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal type of CreateTypeSequence
 */
template <typename Type, typename...T>
struct CreateTypeSequence<1, Type, T...>
    : TypeSequence<Type, T...>
{ };

/**
 * \ingroup meta
 *
 * Creates an empty \c TypeSequence<> for a \c Count = Eigen::Dynamic
 */
template <typename Type>
struct CreateTypeSequence<Eigen::Dynamic, Type>
  : TypeSequence<>
{ };

template <typename Model, typename ParameterProcess>
struct AdaptiveModel { };

/**
 * \ingroup meta
 *
 * Same as CreateTypeSequence, however with a reversed parameter order. This is
 * an attempt to make the use of \c CreateTypeSequence more natural. It also
 * allows dynamic sizes if needed.
 */
template <typename Type, int Count = Eigen::Dynamic>
struct MultipleOf
    : CreateTypeSequence<Count, Type>
{
    template <typename InstanceType>
    explicit
    MultipleOf(InstanceType&& instance, int instance_count = Count)
        : instance(std::forward<InstanceType>(instance)),
          count(instance_count)
    { }

    Type instance;
    int count;
};

/**
 * \internal
 * \ingroup meta
 * \todo fix
 *
 * Creates an empty TypeSequence for dynamic count
 */
//template <typename Type>
//struct MultipleOf<Type, Eigen::Dynamic>
//    : CreateTypeSequence<Eigen::Dynamic, Type>
//{ };

/**
 * \c Join represents a meta operator taking an argument pack which should be
 * unified in a specific way. The operator is defined by the following axioms
 *
 * - Pack of Join<P1, P2, ...>: {P1, P2, ...}
 * - Positive pack:             sizeof...(T) > 0 for Join<T...>
 * - Nesting:                   Join<P1, Join<P2, P3>> = {P1, P2, P3}
 * - Comm.                      Join<P1, Join<P2, P3>> = Join<Join<P1, P2>, P3>
 * - MultipleOf operator:       Join<MultipleOf<P, #>>
 *
 * \ingroup meta
 */
template <typename...T> struct Join;

/**
 * \internal
 * \ingroup meta
 *
 * Collapes the argument pack of the Join operator into Model<T...> of ay given
 * Join<...> operator.
 */
template <typename...T> struct CollapseJoin;

/**
 * \internal
 * \ingroup meta
 *
 * CollapseJoin specialization which expands the type sequence by the Head
 * element assuming Head is neither a Join<...> nor a MultipleOf<P, #> operator.
 */
template <
    typename...S,
    typename Head,
    typename...T,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,                 // Final model type
           TypeSequence<S...>,      // Type sequence holding the pack expansion
           Head,                    // Current non-operator pack head element
           T...>                    // Remaining Tail
  : CollapseJoin<
        Model<>,                    // Final model type
        TypeSequence<Head, S...>,   // updated type sequence
        T...>                       // Remaining Tail
{ };

/**
 * \internal
 * \ingroup meta
 *
 * CollapseJoin specialization which unifies a Join<...> pack Head into the
 * outer Join pack, i.e.
 *
 * Join<T1..., Join<T2...>, T3 > = Join<T1..., T2..., T3...>
 */
template <
    typename...S,
    typename...T,
    typename...U,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,                 // Final model type
           TypeSequence<S...>,      // Type sequence holding the pack expansion
           Join<T...>,              // Current pack head element
           U...>                    // Remaining Tail
  : CollapseJoin<
        Model<>,                    // Final model type
        TypeSequence<S...>,         // Type sequence holding the pack expansion
        T...,                       // Extracted pack from inner Join operator
        U...>                       // Remaining Tail
{ };

/**
 * \internal
 * \ingroup meta
 *
 * CollapseJoin specialization which translates a MultipleOf<P,#> operator,
 * at the head of the pack, into Model<MultipleOf<P, #>>, i.e
 *
 * Join<T1..., MultipleOf<P, 10>, T2...> =
 * Join<T1..., Model<MultipleOf<P, 10>>, T2...>.
 */
template <
    typename...S,
    typename...T,
    typename U,
    int Count,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,                 // Final model type
           TypeSequence<S...>,      // Type sequence holding the pack expansion
           MultipleOf<U, Count>,    // Current pack head element
           T...>                    // Remaining Join pack, the tail
  : CollapseJoin<
        Model<>,                    // Final model type
        TypeSequence<S...>,         // Type sequence holding the pack expansion
        Model<MultipleOf<U, Count>>,// Redefine head in terms of Model<>
        T...>                       // Remaining Tail
{ };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal case of Join operator collapsing. The final result of Join<T...>
 * is Model<U...> where U are all the expanded non operator types.
 */
template <
    typename...S,
    template <typename...> class Model
>
struct CollapseJoin<
           Model<>,
           TypeSequence<S...>>
{
    /**
     * \brief Final type outcome of the Join Operator
     */
    typedef Model<S...> Type;

    static_assert(sizeof...(S) > 1,
                  "Join<A, B, ...> operator must take 2 or more operands");
};

/**
 * \internal
 * \ingroup meta
 *
 * Terminal case of Join operator collapsing for a Join of the form
 * Join<MultipleOf<P, #>> resulting in Model<MultipleOf<P, #>>
 */
template <
    typename M,
    int Count,
    template <typename...> class Model
>
struct CollapseJoin<Model<>, TypeSequence<Model<MultipleOf<M, Count>>>>
{
    typedef Model<MultipleOf<M, Count>> Type;

    static_assert(Count > 0 || Count == -1,
                  "Cannot expand Join<MultipleOf<M, Count>> operator on M. "
                  "Count must be positive or set to -1 for the dynamic size "
                  "case.");
};

/**
 * \ingroup meta
 * Represents any number of available options as defined in #FilterOptions
 */
template <int T> struct Options { enum : signed int { Value = T }; };

/**
 * \ingroup meta
 * Combines multiple options into one. This allows to specify the options
 * listed in an arbitrary number
 */
template <int ... T> struct CombineOptions;

/**
 * \internal
 * \ingroup meta
 *
 * Combines the first option within the option pack with the previous one.
 */
template <int Value, int H, int ... T>
struct CombineOptions<Value, H, T...> : CombineOptions<Value | H, T...> { };

/**
 * \internal
 * \ingroup meta
 *
 * Terminal case CombineOptions
 */
template <int Value>
struct CombineOptions<Value> { typedef fl::Options<Value> Options; };

/**
 * \internal
 * \ingroup meta
 *
 * No Option case
 */
template <>
struct CombineOptions<> { typedef fl::Options<NoOptions> Options; };

}

#endif

<|endoftext|>


<commit_before>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_LINEARELLIPTIC_PROBLEMS_THERMALBLOCK_HH
#define DUNE_HDD_LINEARELLIPTIC_PROBLEMS_THERMALBLOCK_HH

#include <memory>

#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/functions/constant.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/grid/boundaryinfo.hh>

#include <dune/pymor/functions/default.hh>
#include <dune/pymor/functions/checkerboard.hh>

#include "../../../linearelliptic/problems/default.hh"

namespace Dune {
namespace HDD {
namespace LinearElliptic {
namespace Problems {

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim = 1 >
class Thermalblock
{
  static_assert(AlwaysFalse< EntityImp >::value, "Not available for dimRange > 1!");
};

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp >
class Thermalblock< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
  : public Default< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
{
  typedef Default< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 > BaseType;
  typedef Thermalblock< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 > ThisType;

public:
  typedef Pymor::Function::Checkerboard< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
      CheckerboardFunctionType;
  using typename BaseType::DiffusionTensorType;
  using typename BaseType::FunctionType;

  static std::string static_id()
  {
    return BaseType::BaseType::static_id() + ".thermalblock";
  }

  static Stuff::Common::ConfigTree default_config(const std::string sub_name = "")
  {
    typedef Stuff::Functions::Constant< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
        ConstantFunctionType;
    typedef Stuff::Functions::Constant< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, domainDim, domainDim >
        ConstantMatrixFunctionType;
    Stuff::Common::ConfigTree config;
    Stuff::Common::ConfigTree checkerboard_config = CheckerboardFunctionType::default_config();
    checkerboard_config["name"] = "diffusion_factor";
    checkerboard_config["type"] = CheckerboardFunctionType::static_id();
    checkerboard_config["parameter_name"] = "diffusion_factor";
    config.add(checkerboard_config, "diffusion_factor");
    Stuff::Common::ConfigTree diffusion_tensor_config = ConstantMatrixFunctionType::default_config();
    diffusion_tensor_config["name"] = "diffusion_tensor";
    diffusion_tensor_config["type"] = ConstantMatrixFunctionType::static_id();
    config.add(diffusion_tensor_config, "diffusion_tensor");
    Stuff::Common::ConfigTree constant_config = ConstantFunctionType::default_config();
    constant_config["type"] = ConstantFunctionType::static_id();
    constant_config["name"] = "force";
    constant_config["value"] = "1";
    config.add(constant_config, "force");
    constant_config["name"] = "dirichlet";
    constant_config["value"] = "0";
    config.add(constant_config, "dirichlet");
    constant_config["name"] = "neumann";
    config.add(constant_config, "neumann");
    if (sub_name.empty())
      return config;
    else {
      Stuff::Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Stuff::Common::ConfigTree config = default_config(),
                                            const std::string sub_name = static_id())
  {
    const Stuff::Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    std::shared_ptr< CheckerboardFunctionType >
        checkerboard_function(CheckerboardFunctionType::create(cfg.sub("diffusion_factor")));
    return Stuff::Common::make_unique< ThisType >(checkerboard_function,
                                                  BaseType::create_matrix_function("diffusion_tensor", cfg),
                                                  BaseType::create_vector_function("force", cfg),
                                                  BaseType::create_vector_function("dirichlet", cfg),
                                                  BaseType::create_vector_function("neumann", cfg));
  } // ... create(...)

  Thermalblock(const std::shared_ptr< const CheckerboardFunctionType >& checkerboard_function,
               const std::shared_ptr< const DiffusionTensorType >& diffusion_tensor,
               const std::shared_ptr< const FunctionType >& force,
               const std::shared_ptr< const FunctionType >& diffusion,
               const std::shared_ptr< const FunctionType >& neumann)
    : BaseType(checkerboard_function, diffusion_tensor, force, diffusion, neumann)
  {}

  virtual std::string type() const DS_OVERRIDE
  {
    return BaseType::BaseType::static_id() + ".thermalblock";
  }
}; // class Thermalblock< ..., 1 >

} // namespace Problems
namespace DiscreteProblems {

template< class GridImp >
class Thermalblock
{
public:
  typedef GridImp GridType;
  typedef Stuff::Grid::Providers::Cube< GridType > GridProviderType;
private:
  typedef Stuff::Grid::BoundaryInfos::AllDirichlet< typename GridType::LeafIntersection > BoundaryInfoType;
  typedef typename GridType::template Codim< 0 >::Entity EntityType;
  typedef typename GridType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridType::dimension;
public:
  typedef double RangeFieldType;
  static const unsigned int dimRange = 1;
  typedef Problems::Thermalblock< EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > ProblemType;

  static void write_config(const std::string filename, const std::string id)
  {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "[logging]" << std::endl;
    file << "info  = true" << std::endl;
    file << "debug = true" << std::endl;
    file << "file  = false" << std::endl;
    file << "[parameter]" << std::endl;
    file << "0.diffusion_factor = [0.1; 0.1; 1.0; 1.0]" << std::endl;
    file << "1.diffusion_factor = [1.0; 1.0; 0.1; 0.1]" << std::endl;
    file << GridProviderType::default_config(GridProviderType::static_id());
    file << ProblemType::default_config(ProblemType::static_id());
    file << "[pymor]" << std::endl;
    file << "training_set = random" << std::endl;
    file << "num_training_samples = 100" << std::endl;
    file << "reductor = generic" << std::endl;
    file << "extension_algorithm = gram_schmidt" << std::endl;
    file << "extension_algorithm_product = h1_semi" << std::endl;
    file << "greedy_error_norm = h1_semi" << std::endl;
    file << "use_estimator = False" << std::endl;
    file << "max_rb_size = 100" << std::endl;
    file << "target_error = 0.01" << std::endl;
    file << "final_compression = False" << std::endl;
    file << "compression_product = None" << std::endl;
    file << "test_set = training" << std::endl;
    file << "num_test_samples = 100" << std::endl;
    file << "test_error_norm = h1_semi" << std::endl;
    file.close();
  } // ... write_config(...)

  Thermalblock(const std::string id, const std::vector< std::string >& arguments, const bool visualize = true)
  {
    // mpi
    int argc = arguments.size();
    char** argv = Stuff::Common::String::vectorToMainArgs(arguments);
#if HAVE_DUNE_FEM
    Fem::MPIManager::initialize(argc, argv);
#else
    MPIHelper::instance(argc, argv);
#endif

    // configuration
    config_ = Stuff::Common::ConfigTree(argc, argv, id + ".cfg");
    if (!config_.has_sub(id))
      DUNE_THROW_COLORFULLY(Stuff::Exceptions::configuration_error,
                            "Missing sub '" << id << "' in the following ConfigTree:\n\n" << config_);
    filename_ = config_.get(id + ".filename", id);

    // logger
    const Stuff::Common::ConfigTree& logger_config = config_.sub("logging");
    int log_flags = Stuff::Common::LOG_CONSOLE;
    debug_logging_ = logger_config.get< bool >("debug", false);
    if (logger_config.get< bool >("info"))
      log_flags = log_flags | Stuff::Common::LOG_INFO;
    if (debug_logging_)
      log_flags = log_flags | Stuff::Common::LOG_DEBUG;
    if (logger_config.get< bool >("file", false))
      log_flags = log_flags | Stuff::Common::LOG_FILE;
    Stuff::Common::Logger().create(log_flags, id, "", "");
    auto& info  = Stuff::Common::Logger().info();

    Timer timer;
    info << "creating grid with '" << GridProviderType::static_id() << "'... " << std::flush;
    grid_provider_ = GridProviderType::create(config_);
    const auto grid_view = grid_provider_->leaf_view();
    info << " done (took " << timer.elapsed()
         << "s, has " << grid_view->indexSet().size(0) << " element";
    if (grid_view->indexSet().size(0) > 1)
      info << "s";
    info << ")" << std::endl;

    boundary_info_ = Stuff::Common::ConfigTree("type", BoundaryInfoType::static_id());

    info << "setting up ";
    info << "'" << ProblemType::static_id() << "'... " << std::flush;
    timer.reset();
    problem_ = ProblemType::create(config_);
    info << "done (took " << timer.elapsed() << "s)" << std::endl;

    if (visualize) {
      info << "visualizing grid and problem... " << std::flush;
      timer.reset();
      grid_provider_->visualize(boundary_info_, filename_ + ".grid");
      problem_->visualize(*grid_view, filename_ + ".problem");
      info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } // if (visualize)
  } // Thermalblock

  std::string filename() const
  {
    return filename_;
  }

  const Stuff::Common::ConfigTree& config() const
  {
    return config_;
  }

  bool debug_logging() const
  {
    return debug_logging_;
  }

  GridProviderType& grid_provider()
  {
    return *grid_provider_;
  }

  const GridProviderType& grid_provider() const
  {
    return *grid_provider_;
  }

  const Stuff::Common::ConfigTree& boundary_info() const
  {
    return boundary_info_;
  }

  const ProblemType& problem() const
  {
    return *problem_;
  }

private:
  std::string filename_;
  Stuff::Common::ConfigTree config_;
  bool debug_logging_;
  std::unique_ptr< GridProviderType > grid_provider_;
  Stuff::Common::ConfigTree boundary_info_;
  std::unique_ptr< const ProblemType > problem_;
}; // class Thermalblock

} // namespace DiscreteProblems
} // namespace LinearElliptic
} // namespace HDD
} // namespace Dune

#endif // DUNE_HDD_LINEARELLIPTIC_PROBLEMS_THERMALBLOCK_HH
<commit_msg>[linearelliptic...thermalblock] updated config vector syntax<commit_after>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_LINEARELLIPTIC_PROBLEMS_THERMALBLOCK_HH
#define DUNE_HDD_LINEARELLIPTIC_PROBLEMS_THERMALBLOCK_HH

#include <memory>

#include <dune/common/static_assert.hh>
#include <dune/common/timer.hh>

#include <dune/stuff/common/memory.hh>
#include <dune/stuff/functions/constant.hh>
#include <dune/stuff/functions/expression.hh>
#include <dune/stuff/grid/provider/cube.hh>
#include <dune/stuff/grid/boundaryinfo.hh>

#include <dune/pymor/functions/default.hh>
#include <dune/pymor/functions/checkerboard.hh>

#include "../../../linearelliptic/problems/default.hh"

namespace Dune {
namespace HDD {
namespace LinearElliptic {
namespace Problems {

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim = 1 >
class Thermalblock
{
  static_assert(AlwaysFalse< EntityImp >::value, "Not available for dimRange > 1!");
};

template< class EntityImp, class DomainFieldImp, int domainDim, class RangeFieldImp >
class Thermalblock< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
  : public Default< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
{
  typedef Default< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 > BaseType;
  typedef Thermalblock< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 > ThisType;

public:
  typedef Pymor::Function::Checkerboard< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
      CheckerboardFunctionType;
  using typename BaseType::DiffusionTensorType;
  using typename BaseType::FunctionType;

  static std::string static_id()
  {
    return BaseType::BaseType::static_id() + ".thermalblock";
  }

  static Stuff::Common::ConfigTree default_config(const std::string sub_name = "")
  {
    typedef Stuff::Functions::Constant< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, 1 >
        ConstantFunctionType;
    typedef Stuff::Functions::Constant< EntityImp, DomainFieldImp, domainDim, RangeFieldImp, domainDim, domainDim >
        ConstantMatrixFunctionType;
    Stuff::Common::ConfigTree config;
    Stuff::Common::ConfigTree checkerboard_config = CheckerboardFunctionType::default_config();
    checkerboard_config["name"] = "diffusion_factor";
    checkerboard_config["type"] = CheckerboardFunctionType::static_id();
    checkerboard_config["parameter_name"] = "diffusion_factor";
    config.add(checkerboard_config, "diffusion_factor");
    Stuff::Common::ConfigTree diffusion_tensor_config = ConstantMatrixFunctionType::default_config();
    diffusion_tensor_config["name"] = "diffusion_tensor";
    diffusion_tensor_config["type"] = ConstantMatrixFunctionType::static_id();
    config.add(diffusion_tensor_config, "diffusion_tensor");
    Stuff::Common::ConfigTree constant_config = ConstantFunctionType::default_config();
    constant_config["type"] = ConstantFunctionType::static_id();
    constant_config["name"] = "force";
    constant_config["value"] = "1";
    config.add(constant_config, "force");
    constant_config["name"] = "dirichlet";
    constant_config["value"] = "0";
    config.add(constant_config, "dirichlet");
    constant_config["name"] = "neumann";
    config.add(constant_config, "neumann");
    if (sub_name.empty())
      return config;
    else {
      Stuff::Common::ConfigTree tmp;
      tmp.add(config, sub_name);
      return tmp;
    }
  } // ... default_config(...)

  static std::unique_ptr< ThisType > create(const Stuff::Common::ConfigTree config = default_config(),
                                            const std::string sub_name = static_id())
  {
    const Stuff::Common::ConfigTree cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
    std::shared_ptr< CheckerboardFunctionType >
        checkerboard_function(CheckerboardFunctionType::create(cfg.sub("diffusion_factor")));
    return Stuff::Common::make_unique< ThisType >(checkerboard_function,
                                                  BaseType::create_matrix_function("diffusion_tensor", cfg),
                                                  BaseType::create_vector_function("force", cfg),
                                                  BaseType::create_vector_function("dirichlet", cfg),
                                                  BaseType::create_vector_function("neumann", cfg));
  } // ... create(...)

  Thermalblock(const std::shared_ptr< const CheckerboardFunctionType >& checkerboard_function,
               const std::shared_ptr< const DiffusionTensorType >& diffusion_tensor,
               const std::shared_ptr< const FunctionType >& force,
               const std::shared_ptr< const FunctionType >& diffusion,
               const std::shared_ptr< const FunctionType >& neumann)
    : BaseType(checkerboard_function, diffusion_tensor, force, diffusion, neumann)
  {}

  virtual std::string type() const DS_OVERRIDE
  {
    return BaseType::BaseType::static_id() + ".thermalblock";
  }
}; // class Thermalblock< ..., 1 >

} // namespace Problems
namespace DiscreteProblems {

template< class GridImp >
class Thermalblock
{
public:
  typedef GridImp GridType;
  typedef Stuff::Grid::Providers::Cube< GridType > GridProviderType;
private:
  typedef Stuff::Grid::BoundaryInfos::AllDirichlet< typename GridType::LeafIntersection > BoundaryInfoType;
  typedef typename GridType::template Codim< 0 >::Entity EntityType;
  typedef typename GridType::ctype DomainFieldType;
  static const unsigned int dimDomain = GridType::dimension;
public:
  typedef double RangeFieldType;
  static const unsigned int dimRange = 1;
  typedef Problems::Thermalblock< EntityType, DomainFieldType, dimDomain, RangeFieldType, dimRange > ProblemType;

  static void write_config(const std::string filename, const std::string id)
  {
    std::ofstream file;
    file.open(filename);
    file << "[" << id << "]" << std::endl;
    file << "filename = " << id << std::endl;
    file << "[logging]" << std::endl;
    file << "info  = true" << std::endl;
    file << "debug = true" << std::endl;
    file << "file  = false" << std::endl;
    file << "[parameter]" << std::endl;
    file << "0.diffusion_factor = [0.1 0.1 1.0 1.0]" << std::endl;
    file << "1.diffusion_factor = [1.0 1.0 0.1 0.1]" << std::endl;
    file << GridProviderType::default_config(GridProviderType::static_id());
    file << ProblemType::default_config(ProblemType::static_id());
    file << "[pymor]" << std::endl;
    file << "training_set = random" << std::endl;
    file << "num_training_samples = 100" << std::endl;
    file << "reductor = generic" << std::endl;
    file << "extension_algorithm = gram_schmidt" << std::endl;
    file << "extension_algorithm_product = h1_semi" << std::endl;
    file << "greedy_error_norm = h1_semi" << std::endl;
    file << "use_estimator = False" << std::endl;
    file << "max_rb_size = 100" << std::endl;
    file << "target_error = 0.01" << std::endl;
    file << "final_compression = False" << std::endl;
    file << "compression_product = None" << std::endl;
    file << "test_set = training" << std::endl;
    file << "num_test_samples = 100" << std::endl;
    file << "test_error_norm = h1_semi" << std::endl;
    file.close();
  } // ... write_config(...)

  Thermalblock(const std::string id, const std::vector< std::string >& arguments, const bool visualize = true)
  {
    // mpi
    int argc = arguments.size();
    char** argv = Stuff::Common::String::vectorToMainArgs(arguments);
#if HAVE_DUNE_FEM
    Fem::MPIManager::initialize(argc, argv);
#else
    MPIHelper::instance(argc, argv);
#endif

    // configuration
    config_ = Stuff::Common::ConfigTree(argc, argv, id + ".cfg");
    if (!config_.has_sub(id))
      DUNE_THROW_COLORFULLY(Stuff::Exceptions::configuration_error,
                            "Missing sub '" << id << "' in the following ConfigTree:\n\n" << config_);
    filename_ = config_.get(id + ".filename", id);

    // logger
    const Stuff::Common::ConfigTree& logger_config = config_.sub("logging");
    int log_flags = Stuff::Common::LOG_CONSOLE;
    debug_logging_ = logger_config.get< bool >("debug", false);
    if (logger_config.get< bool >("info"))
      log_flags = log_flags | Stuff::Common::LOG_INFO;
    if (debug_logging_)
      log_flags = log_flags | Stuff::Common::LOG_DEBUG;
    if (logger_config.get< bool >("file", false))
      log_flags = log_flags | Stuff::Common::LOG_FILE;
    Stuff::Common::Logger().create(log_flags, id, "", "");
    auto& info  = Stuff::Common::Logger().info();

    Timer timer;
    info << "creating grid with '" << GridProviderType::static_id() << "'... " << std::flush;
    grid_provider_ = GridProviderType::create(config_);
    const auto grid_view = grid_provider_->leaf_view();
    info << " done (took " << timer.elapsed()
         << "s, has " << grid_view->indexSet().size(0) << " element";
    if (grid_view->indexSet().size(0) > 1)
      info << "s";
    info << ")" << std::endl;

    boundary_info_ = Stuff::Common::ConfigTree("type", BoundaryInfoType::static_id());

    info << "setting up ";
    info << "'" << ProblemType::static_id() << "'... " << std::flush;
    timer.reset();
    problem_ = ProblemType::create(config_);
    info << "done (took " << timer.elapsed() << "s)" << std::endl;

    if (visualize) {
      info << "visualizing grid and problem... " << std::flush;
      timer.reset();
      grid_provider_->visualize(boundary_info_, filename_ + ".grid");
      problem_->visualize(*grid_view, filename_ + ".problem");
      info << "done (took " << timer.elapsed() << "s)" << std::endl;
    } // if (visualize)
  } // Thermalblock

  std::string filename() const
  {
    return filename_;
  }

  const Stuff::Common::ConfigTree& config() const
  {
    return config_;
  }

  bool debug_logging() const
  {
    return debug_logging_;
  }

  GridProviderType& grid_provider()
  {
    return *grid_provider_;
  }

  const GridProviderType& grid_provider() const
  {
    return *grid_provider_;
  }

  const Stuff::Common::ConfigTree& boundary_info() const
  {
    return boundary_info_;
  }

  const ProblemType& problem() const
  {
    return *problem_;
  }

private:
  std::string filename_;
  Stuff::Common::ConfigTree config_;
  bool debug_logging_;
  std::unique_ptr< GridProviderType > grid_provider_;
  Stuff::Common::ConfigTree boundary_info_;
  std::unique_ptr< const ProblemType > problem_;
}; // class Thermalblock

} // namespace DiscreteProblems
} // namespace LinearElliptic
} // namespace HDD
} // namespace Dune

#endif // DUNE_HDD_LINEARELLIPTIC_PROBLEMS_THERMALBLOCK_HH
<|endoftext|>


<commit_before>#include <scitbx/array_family/boost_python/flex_fwd.h>

#include <scitbx/array_family/boost_python/flex_wrapper.h>
#include <scitbx/serialization/single_buffered.h>
#include <scitbx/matrix/transpose_multiply.h>
#include <scitbx/math/utils.h>
#include <scitbx/array_family/tiny_types.h>
#include <boost/python/make_constructor.hpp>
#include <boost/python/args.hpp>
#include <boost/python/return_arg.hpp>
#include <boost/format.hpp>
#include <scitbx/array_family/boost_python/flex_helpers.h>

namespace scitbx { namespace serialization { namespace single_buffered {

  inline
  char* to_string(char* start, scitbx::af::int6 const& value)
  {
    return
      to_string(to_string(to_string(to_string(to_string(to_string(
        start, value[0]), value[1]), value[2]), value[0]), value[1]), value[2]);
  }

  template <>
  struct from_string<scitbx::af::int6>
  {
    from_string(const char* start)
    {
      end = start;
      for(std::size_t i=0;i<6;i++) {
        from_string<int> proxy(end);
        value[i] = proxy.value;
        end = proxy.end;
      }
    }

    scitbx::af::int6 value;
    const char* end;
  };

}}} // namespace scitbx::serialization::single_buffered

#include <scitbx/array_family/boost_python/flex_pickle_single_buffered.h>

namespace scitbx { namespace af { namespace boost_python {

  template <>
  struct flex_default_element<scitbx::af::int6>
  {
    static scitbx::af::int6
    get() { return scitbx::af::int6(0,0,0,0,0,0); }
  };

}}}

namespace dials { namespace af {
namespace {

  scitbx::af::flex<scitbx::af::int6>::type*
  join(
    scitbx::af::const_ref<int> const& a,
    scitbx::af::const_ref<int> const& b,
    scitbx::af::const_ref<int> const& c,
    scitbx::af::const_ref<int> const& d,
    scitbx::af::const_ref<int> const& e,
    scitbx::af::const_ref<int> const& f)
  {
    SCITBX_ASSERT(a.size() == b.size());
    SCITBX_ASSERT(a.size() == c.size());
    SCITBX_ASSERT(a.size() == d.size());
    SCITBX_ASSERT(a.size() == e.size());
    SCITBX_ASSERT(a.size() == f.size());
    scitbx::af::shared<scitbx::af::int6> result((scitbx::af::reserve(a.size())));
    for(std::size_t i=0;i<a.size();i++) {
      result.push_back(scitbx::af::int6(a[i],b[i],c[i],d[i],e[i],f[i]));
    }
    return new scitbx::af::flex<scitbx::af::int6>::type(result, result.size());
  }

  scitbx::af::flex<scitbx::af::int6>::type*
  from_int(
    scitbx::af::const_ref<int> const& x)
  {
    SCITBX_ASSERT(x.size() % 6 == 0);
    std::size_t result_size = x.size() / 6;
    scitbx::af::shared<scitbx::af::int6> result(result_size);
    const int* d = x.begin();
    for(std::size_t i=0;i<result_size;i++) {
      for (std::size_t j=0;j<6;++j) {
        result[i][j] = *d++;
      }
    }
    return new scitbx::af::flex<scitbx::af::int6>::type(result, result.size());
  }

  scitbx::af::flex_int
  as_int(scitbx::af::flex<scitbx::af::int6>::type const& a)
  {
    SCITBX_ASSERT(a.accessor().is_trivial_1d());
    scitbx::af::flex_int result(a.size()*6, scitbx::af::init_functor_null<int>());
    int* r = result.begin();
    scitbx::af::const_ref<scitbx::af::int6> a_ref = a.const_ref().as_1d();
    for(std::size_t i=0;i<a_ref.size();i++) {
      for(std::size_t j=0;j<6;j++) {
        *r++ = a_ref[i][j];
      }
    }
    return result;
  }

} // namespace <anonymous>

namespace boost_python {

  void export_flex_int6()
  {
    using namespace boost::python;
    using boost::python::arg;
    typedef scitbx::af::boost_python::flex_wrapper<scitbx::af::int6> f_w;
    f_w::plain("int6")
      .def_pickle(scitbx::af::boost_python::flex_pickle_single_buffered<
        scitbx::af::int6,
        6*scitbx::af::boost_python::pickle_size_per_element<int>::value>())
      .def("__init__", make_constructor(join))
      .def("__init__", make_constructor(from_int))
      .def("as_int", as_int);
    ;
  }

}}} // namespace scitbx::af::boost_python
<commit_msg>Fixed bug in pickling<commit_after>#include <scitbx/array_family/boost_python/flex_fwd.h>

#include <scitbx/array_family/boost_python/flex_wrapper.h>
#include <scitbx/serialization/single_buffered.h>
#include <scitbx/matrix/transpose_multiply.h>
#include <scitbx/math/utils.h>
#include <scitbx/array_family/tiny_types.h>
#include <boost/python/make_constructor.hpp>
#include <boost/python/args.hpp>
#include <boost/python/return_arg.hpp>
#include <boost/format.hpp>
#include <scitbx/array_family/boost_python/flex_helpers.h>

namespace scitbx { namespace serialization { namespace single_buffered {

  inline
  char* to_string(char* start, scitbx::af::int6 const& value)
  {
    return
      to_string(to_string(to_string(to_string(to_string(to_string(
        start, value[0]), value[1]), value[2]), value[3]), value[4]), value[5]);
  }

  template <>
  struct from_string<scitbx::af::int6>
  {
    from_string(const char* start)
    {
      end = start;
      for(std::size_t i=0;i<6;i++) {
        from_string<int> proxy(end);
        value[i] = proxy.value;
        end = proxy.end;
      }
    }

    scitbx::af::int6 value;
    const char* end;
  };

}}} // namespace scitbx::serialization::single_buffered

#include <scitbx/array_family/boost_python/flex_pickle_single_buffered.h>

namespace scitbx { namespace af { namespace boost_python {

  template <>
  struct flex_default_element<scitbx::af::int6>
  {
    static scitbx::af::int6
    get() { return scitbx::af::int6(0,0,0,0,0,0); }
  };

}}}

namespace dials { namespace af {
namespace {

  scitbx::af::flex<scitbx::af::int6>::type*
  join(
    scitbx::af::const_ref<int> const& a,
    scitbx::af::const_ref<int> const& b,
    scitbx::af::const_ref<int> const& c,
    scitbx::af::const_ref<int> const& d,
    scitbx::af::const_ref<int> const& e,
    scitbx::af::const_ref<int> const& f)
  {
    SCITBX_ASSERT(a.size() == b.size());
    SCITBX_ASSERT(a.size() == c.size());
    SCITBX_ASSERT(a.size() == d.size());
    SCITBX_ASSERT(a.size() == e.size());
    SCITBX_ASSERT(a.size() == f.size());
    scitbx::af::shared<scitbx::af::int6> result((scitbx::af::reserve(a.size())));
    for(std::size_t i=0;i<a.size();i++) {
      result.push_back(scitbx::af::int6(a[i],b[i],c[i],d[i],e[i],f[i]));
    }
    return new scitbx::af::flex<scitbx::af::int6>::type(result, result.size());
  }

  scitbx::af::flex<scitbx::af::int6>::type*
  from_int(
    scitbx::af::const_ref<int> const& x)
  {
    SCITBX_ASSERT(x.size() % 6 == 0);
    std::size_t result_size = x.size() / 6;
    scitbx::af::shared<scitbx::af::int6> result(result_size);
    const int* d = x.begin();
    for(std::size_t i=0;i<result_size;i++) {
      for (std::size_t j=0;j<6;++j) {
        result[i][j] = *d++;
      }
    }
    return new scitbx::af::flex<scitbx::af::int6>::type(result, result.size());
  }

  scitbx::af::flex_int
  as_int(scitbx::af::flex<scitbx::af::int6>::type const& a)
  {
    SCITBX_ASSERT(a.accessor().is_trivial_1d());
    scitbx::af::flex_int result(a.size()*6, scitbx::af::init_functor_null<int>());
    int* r = result.begin();
    scitbx::af::const_ref<scitbx::af::int6> a_ref = a.const_ref().as_1d();
    for(std::size_t i=0;i<a_ref.size();i++) {
      for(std::size_t j=0;j<6;j++) {
        *r++ = a_ref[i][j];
      }
    }
    return result;
  }

} // namespace <anonymous>

namespace boost_python {

  void export_flex_int6()
  {
    using namespace boost::python;
    using boost::python::arg;
    typedef scitbx::af::boost_python::flex_wrapper<scitbx::af::int6> f_w;
    f_w::plain("int6")
      .def_pickle(scitbx::af::boost_python::flex_pickle_single_buffered<
        scitbx::af::int6,
        6*scitbx::af::boost_python::pickle_size_per_element<int>::value>())
      .def("__init__", make_constructor(join))
      .def("__init__", make_constructor(from_int))
      .def("as_int", as_int);
    ;
  }

}}} // namespace scitbx::af::boost_python
<|endoftext|>


<commit_before>#ifndef _COMMON_HPP_
#define _COMMON_HPP_

#include <map>
#include <string>
#include <vector>

// Simple tuple class for reading triples of data
class Tuple {
public:
    Tuple(int x, int y, int z) : first(x), second(y), third(z) {}
    int first;
    int second;
    int third;
};

// Python 2.x range() function.  Returns the vector of elements
// (start, ..., end - 1).
std::vector<int> Range(int start, int end);

// Range starting from 0.
std::vector<int> Range(int end);

// Data sets
enum {
    WIKI_VOTE=0,
    EMAIL_EU,
    WIKI_TALK,
    SOC_EPINIONS,
    SLASHDOT,
    AS_CAIDA,
    AMAZON,
    TWITTER,
    WIKI_RFA,
    CIT_HEP_PH,
    WEB_STANFORD,
    EMAIL_ENRON,
    DBLP,
};

const int kNumNetworks = 13;

// Algorithms
enum {
    TENSOR,                 // Tensor Spectral Clustering (TSC)
    DIRLAP,                 // Chung's directed Laplacian
    LAP,                    // Laplacian with all edges considered undirected
    CO_U,                   // Co-clustering (left singular vector)
    CO_V,                   // Co-clustering (right singular vector)
    D3C_ONLY_DIRLAP,        // Directed laplacian, but only look at D3C subgraph
    D3C_ONLY_RECIP_DIRLAP,  // Directed laplacian, but only look at D3C
                            // + reciprocated edges subgraph
    D3C_ONLY_NOBACK_DIRLAP, // Directed laplacian, but only look at D3C with
                            // no back edges subgraph
    ASYMMETRIC_LAP,         // Asymmetric laplacian
    RANDOM,                 // Random order sweep cut
};

// Cut types
enum {
    D3C_COND,             // cut3(S) / min(vol3(S), vol3(Sbar))
    D3C_COND_2NODE,       // max(#(D3C cut w/ 2 nodes in S)    / #(D3C w/ >= 2 nodes in S),
                          //     #(D3C cut w/ 2 nodes in Sbar) / #(D3C w/ >= 2 nodes in Sbar))
    D3C_EXPANSION,        // cut3(S) / min(|S|, |Sbar|)
    D3C_NORMALIZED,       // cut3(S) (1 / vol3(S) + 1 / vol3(Sbar))
    D3C_COND_RECIP,       // D3C_COND, but count reciprocated edges
    D3C_TOUCH,            // cut3(S) / min(vol(V) - vol(S), vol(V) - vol(Sbar))
    D3C_EXPANSION_RECIP,  // D3C_EXPANSION, but count reciprocated edges
    D3C_NOBACK_COND,      // D3C_COND, but only look at D3Cs with no back edges
    BIPARTITE,            // Number of edges cut
    NORMALIZED,           // normalized cut (assume undirected)
    COND,                 // conductance (assume undirected)
    EXPANSION,            // cut(S) / min(|S|, |Sbar|)
    DENSITY,              // Maximum density of S, Sbar
};

// Triple types
enum {
    D3CS,         // Directed 3-cycles
    D3CS_RECIP,   // Directed 3-cycles and reciprocated edges
    D3CS_NOBACK,  // Directed 3-cycles with no back edges
    OPEN_TRIS,    // Open triangles
};

// Given a network, return the text file name.
std::string NetworkStr(int network);

// Given an algorithm, return the name of the algorithm.
std::string AlgStr(int algorithm);

// Print information about the networks.
void PrintHelp();

#endif  // _COMMON_HPP_
<commit_msg>clean up old code<commit_after>#ifndef _COMMON_HPP_
#define _COMMON_HPP_

#include <map>
#include <string>
#include <vector>

// Simple tuple class for reading triples of data
class Tuple {
public:
    Tuple(int x, int y, int z) : first(x), second(y), third(z) {}
    int first;
    int second;
    int third;
};

// Python 2.x range() function.  Returns the vector of elements
// (start, ..., end - 1).
std::vector<int> Range(int start, int end);

// Range starting from 0.
std::vector<int> Range(int end);

// Data sets
enum {
    WIKI_VOTE=0,
    EMAIL_EU,
    WIKI_TALK,
    SOC_EPINIONS,
    SLASHDOT,
    AS_CAIDA,
    AMAZON,
    TWITTER,
    WIKI_RFA,
    CIT_HEP_PH,
    WEB_STANFORD,
    EMAIL_ENRON,
    DBLP,
};

const int kNumNetworks = 13;

// Algorithms
enum {
    TENSOR,                 // Tensor Spectral Clustering (TSC)
    DIRLAP,                 // Chung's directed Laplacian
    LAP,                    // Laplacian with all edges considered undirected
    CO_U,                   // Co-clustering (left singular vector)
    CO_V,                   // Co-clustering (right singular vector)
    D3C_ONLY_DIRLAP,        // Directed laplacian, but only look at D3C subgraph
    D3C_ONLY_RECIP_DIRLAP,  // Directed laplacian, but only look at D3C
                            // + reciprocated edges subgraph
    D3C_ONLY_NOBACK_DIRLAP, // Directed laplacian, but only look at D3C with
                            // no back edges subgraph
    ASYMMETRIC_LAP,         // Asymmetric laplacian
    RANDOM,                 // Random order sweep cut
};

// Cut types
enum {
    D3C_COND,             // cut3(S) / min(vol3(S), vol3(Sbar))
    D3C_EXPANSION,        // cut3(S) / min(|S|, |Sbar|)
    D3C_NORMALIZED,       // cut3(S) (1 / vol3(S) + 1 / vol3(Sbar))
    D3C_COND_RECIP,       // D3C_COND, but count reciprocated edges
    D3C_EXPANSION_RECIP,  // D3C_EXPANSION, but count reciprocated edges
    D3C_NOBACK_COND,      // D3C_COND, but only look at D3Cs with no back edges
    BIPARTITE,            // Number of edges cut
    NORMALIZED,           // normalized cut (assume undirected)
    COND,                 // conductance (assume undirected)
    EXPANSION,            // cut(S) / min(|S|, |Sbar|)
    DENSITY,              // Maximum density of S, Sbar
};

// Triple types
enum {
    D3CS,         // Directed 3-cycles
    D3CS_RECIP,   // Directed 3-cycles and reciprocated edges
    D3CS_NOBACK,  // Directed 3-cycles with no back edges
    OPEN_TRIS,    // Open triangles
};

// Given a network, return the text file name.
std::string NetworkStr(int network);

// Given an algorithm, return the name of the algorithm.
std::string AlgStr(int algorithm);

// Print information about the networks.
void PrintHelp();

#endif  // _COMMON_HPP_
<|endoftext|>


<commit_before>

#include <sstream>

#include <boost/foreach.hpp>

#include <H5Cpp.h>

#include "flame/h5writer.h"
#include "flame/h5loader.h"

// H5::Exception doesn't derive from std::exception
// so translate to some type which does.
// TODO: sub-class mixing H5::Exception and std::exception?
#define CATCH() catch(H5::Exception& he) { \
    std::ostringstream strm; \
    strm<<"H5 Error "<<he.getDetailMsg(); \
    throw std::runtime_error(strm.str()); \
    }

namespace {
struct StateElement {
    unsigned idx;
    StateBase::ArrayInfo info;
    H5::DataSet dset;
    std::vector<hsize_t> shape;
    H5::DataSpace memspace;
};
}

struct H5StateWriter::Pvt {
    H5::H5File file;
    H5::Group group;
    std::vector<StateElement> elements;
};

H5StateWriter::H5StateWriter() :pvt(new Pvt) {}

H5StateWriter::H5StateWriter(const char *spec) :pvt(new Pvt)
{
    open(spec);
}

H5StateWriter::H5StateWriter(const std::string& spec) :pvt(new Pvt)
{
    open(spec);
}

H5StateWriter::~H5StateWriter()
{
    try{
        close();
    } catch(std::runtime_error& e) {
        std::cerr<<"H5StateWriter is ignoring exception in dtor : "<<e.what()<<"\n";
    }
    delete pvt;
}

void H5StateWriter::open(const char *spec)
{
    open(std::string(spec));
}

void H5StateWriter::open(const std::string& spec)
{
    try {
        close();
        /* The provided spec may contain both file path and group(s)
         * seperated by '/' which is ambigious as the file path
         * may contain '/' as well...
         * so do as h5ls does and strip off from the right hand side until
         * and try to open while '/' remain.
         */
        size_t sep = spec.npos;

        while(true) {
            sep = spec.find_last_of('/', sep-1);

            std::string fname(spec.substr(0, sep));

            try {
                pvt->file.openFile(fname, H5F_ACC_RDWR|H5F_ACC_CREAT);
            } catch(H5::FileIException& e) {
                if(sep==spec.npos) {
                    // no more '/' so this is failure
                    throw std::runtime_error("Unable to open file");
                }
                continue; // keep trying
            } CATCH()

            if(sep!=spec.npos) {
                std::string group(spec.substr(sep+1));
                // delete group if it already exists
                try{
                    H5G_stat_t stat;
                    pvt->file.getObjinfo(group, stat);
                    pvt->file.unlink(group);
                } catch(H5::FileIException&) {
                    // ignore non-existant
                }

                pvt->group = pvt->file.createGroup(group);
            } else {
                //TODO: cleanup root?

                pvt->group = pvt->file.openGroup("/");
            }

            return;
        }
    } CATCH()
}

void H5StateWriter::close()
{
    try{
        pvt->group.close();
        pvt->file.close();
    }CATCH()
}

void H5StateWriter::prepare(const StateBase *RS)
{
    try {
        // hack since getArray() is non-const
        // we won't actually modify the state
        StateBase *S = const_cast<StateBase*>(RS);

        assert(pvt->elements.empty());

        for(unsigned idx=0; true; idx++) {
            StateBase::ArrayInfo info;

            if(!S->getArray(idx, info))
                break;

            H5::DataType dtype;
            switch(info.type) {
            case StateBase::ArrayInfo::Double:
                dtype = H5::DataType(H5::PredType::NATIVE_DOUBLE);
                break;
            case StateBase::ArrayInfo::Sizet:
                if(sizeof(size_t)==8)
                    dtype = H5::DataType(H5::PredType::NATIVE_UINT64);
                else if(sizeof(size_t)==4)
                    dtype = H5::DataType(H5::PredType::NATIVE_UINT32);
                else
                    throw std::logic_error("unsupported size_t");
                break;
            default:
                continue; // TODO string
            }

            StateElement elem;
            elem.idx = idx;
            elem.info = info;

            // first dim is simulation "time"
            std::vector<hsize_t> dims   (info.ndim+1),
                                 maxdims(info.ndim+1, H5S_UNLIMITED);
            std::copy(info.dim,
                      info.dim+info.ndim,
                      dims.begin()+1);

            elem.shape = dims; // copy

            // size w/ first dim==0
            dims[0] = 0;

            H5::DataSpace dspace(dims.size(), &dims[0], &maxdims[0]);

            dims[0] = 10; // chunk size in "time" steps
            // other chunk sizes are multiple of initial size
            H5::DSetCreatPropList props;
            props.setChunk(dims.size(), &dims[0]);

            // memspace is simple from origin to [1,shape]
            dims[0] = 1;
            elem.memspace = H5::DataSpace(dims.size(), &dims[0]);

            elem.dset = pvt->group.createDataSet(info.name, dtype, dspace, props);

            pvt->elements.push_back(elem);
        }

        if(pvt->elements.empty()) {
            throw std::logic_error("state type has not elements to store?");
        }
    } CATCH()
}

void H5StateWriter::append(const StateBase *RS)
{
    try {
        StateBase *S = const_cast<StateBase*>(RS);

        if(pvt->elements.empty())
            prepare(RS);

        BOOST_FOREACH(StateElement& elem, pvt->elements)
        {
            StateBase::ArrayInfo info;

            if(!S->getArray(elem.idx, info))
                throw std::logic_error("can't re-fetch state parameter?");

            assert((elem.info.ndim==info.ndim) && (elem.info.type==info.type));

            size_t index = elem.shape[0]; // we will write data[index,...]
            elem.shape[0]++;

            std::copy(info.dim,
                      info.dim+info.ndim,
                      elem.shape.begin()+1);

            elem.dset.extend(&elem.shape[0]); // resize

            // filespace is hyper from [index,0...] to [index,shape]
            std::vector<hsize_t> start(elem.shape.size(), 0);
            start[0] = index;

            elem.shape[0] = 1; // reuse as count

            H5::DataSpace filespace(elem.dset.getSpace());
            filespace.selectHyperslab(H5S_SELECT_SET, &elem.shape[0], &start[0]);

            H5::DataType dtype(elem.dset.getDataType());

            elem.dset.write(info.ptr, dtype, elem.memspace, filespace);

            elem.shape[0] = index+1;
        }
    } CATCH()
}

void H5StateWriter::setAttr(const char *name, const char *val)
{
    try {
        if(H5Aexists(pvt->group.getId(), name)>0)
        //if(pvt->group.attrExists(name)) // H5Aexists was added in 1.8.0, c++ wrapper wasn't added until later...
        {
            pvt->group.removeAttr(name);
        }

        {
            H5::DataSpace scalar;
            H5::StrType dtype(H5::PredType::C_S1, std::max((size_t)16u, strlen(val)));
            H5::Attribute attr(pvt->group.createAttribute(name, dtype, scalar));
            attr.write(dtype, val);
        }
    } CATCH()
}

void H5StateWriter::dontPrint()
{
    try {
        H5::Exception::dontPrint();
    }CATCH()
}
<commit_msg>h5writer handle resize<commit_after>

#include <sstream>

#include <boost/foreach.hpp>

#include <H5Cpp.h>

#include "flame/h5writer.h"
#include "flame/h5loader.h"

// H5::Exception doesn't derive from std::exception
// so translate to some type which does.
// TODO: sub-class mixing H5::Exception and std::exception?
#define CATCH() catch(H5::Exception& he) { \
    std::ostringstream strm; \
    strm<<"H5 Error "<<he.getDetailMsg(); \
    throw std::runtime_error(strm.str()); \
    }

namespace {
struct StateElement {
    unsigned idx;
    StateBase::ArrayInfo info;
    H5::DataSet dset;
    size_t nextrow;
    StateElement() :nextrow(0u) {}
};
}

struct H5StateWriter::Pvt {
    H5::H5File file;
    H5::Group group;
    std::vector<StateElement> elements;
};

H5StateWriter::H5StateWriter() :pvt(new Pvt) {}

H5StateWriter::H5StateWriter(const char *spec) :pvt(new Pvt)
{
    open(spec);
}

H5StateWriter::H5StateWriter(const std::string& spec) :pvt(new Pvt)
{
    open(spec);
}

H5StateWriter::~H5StateWriter()
{
    try{
        close();
    } catch(std::runtime_error& e) {
        std::cerr<<"H5StateWriter is ignoring exception in dtor : "<<e.what()<<"\n";
    }
    delete pvt;
}

void H5StateWriter::open(const char *spec)
{
    open(std::string(spec));
}

void H5StateWriter::open(const std::string& spec)
{
    try {
        close();
        /* The provided spec may contain both file path and group(s)
         * seperated by '/' which is ambigious as the file path
         * may contain '/' as well...
         * so do as h5ls does and strip off from the right hand side until
         * and try to open while '/' remain.
         */
        size_t sep = spec.npos;

        while(true) {
            sep = spec.find_last_of('/', sep-1);

            std::string fname(spec.substr(0, sep));

            try {
                pvt->file.openFile(fname, H5F_ACC_RDWR|H5F_ACC_CREAT);
            } catch(H5::FileIException& e) {
                if(sep==spec.npos) {
                    // no more '/' so this is failure
                    throw std::runtime_error("Unable to open file");
                }
                continue; // keep trying
            } CATCH()

            if(sep!=spec.npos) {
                std::string group(spec.substr(sep+1));
                // delete group if it already exists
                try{
                    H5G_stat_t stat;
                    pvt->file.getObjinfo(group, stat);
                    pvt->file.unlink(group);
                } catch(H5::FileIException&) {
                    // ignore non-existant
                }

                pvt->group = pvt->file.createGroup(group);
            } else {
                //TODO: cleanup root?

                pvt->group = pvt->file.openGroup("/");
            }

            return;
        }
    } CATCH()
}

void H5StateWriter::close()
{
    try{
        pvt->group.close();
        pvt->file.close();
    }CATCH()
}

void H5StateWriter::prepare(const StateBase *RS)
{
    try {
        // hack since getArray() is non-const
        // we won't actually modify the state
        StateBase *S = const_cast<StateBase*>(RS);

        assert(pvt->elements.empty());

        for(unsigned idx=0; true; idx++) {
            StateBase::ArrayInfo info;

            if(!S->getArray(idx, info))
                break;

            H5::DataType dtype;
            switch(info.type) {
            case StateBase::ArrayInfo::Double:
                dtype = H5::DataType(H5::PredType::NATIVE_DOUBLE);
                break;
            case StateBase::ArrayInfo::Sizet:
                if(sizeof(size_t)==8)
                    dtype = H5::DataType(H5::PredType::NATIVE_UINT64);
                else if(sizeof(size_t)==4)
                    dtype = H5::DataType(H5::PredType::NATIVE_UINT32);
                else
                    throw std::logic_error("unsupported size_t");
                break;
            default:
                continue; // TODO string
            }

            StateElement elem;
            elem.idx = idx;
            elem.info = info;

            // first dim is simulation "time"
            hsize_t dims[StateBase::ArrayInfo::maxdims+1],
                    maxdims[StateBase::ArrayInfo::maxdims+1];
            std::fill(maxdims, maxdims+info.ndim+1, H5S_UNLIMITED);
            std::copy(info.dim,
                      info.dim+info.ndim,
                      dims+1);

            // size w/ first dim==0
            dims[0] = 0;

            H5::DataSpace dspace(info.ndim+1, &dims[0], &maxdims[0]);

            dims[0] = 1024; // chunk size in "time" steps (arbitrary)
            // other chunk sizes are multiple of initial size
            H5::DSetCreatPropList props;
            props.setChunk(info.ndim+1, &dims[0]);

            // memspace is simple from origin to [1,shape]
            dims[0] = 1;

            elem.dset = pvt->group.createDataSet(info.name, dtype, dspace, props);

            pvt->elements.push_back(elem);
        }

        if(pvt->elements.empty()) {
            throw std::logic_error("state type has not elements to store?");
        }
    } CATCH()
}

void H5StateWriter::append(const StateBase *RS)
{
    try {
        StateBase *S = const_cast<StateBase*>(RS);

        if(pvt->elements.empty())
            prepare(RS);

        BOOST_FOREACH(StateElement& elem, pvt->elements)
        {
            StateBase::ArrayInfo info;

            if(!S->getArray(elem.idx, info))
                throw std::logic_error("can't re-fetch state parameter?");

            assert((elem.info.ndim==info.ndim) && (elem.info.type==info.type));

            hsize_t shape[StateBase::ArrayInfo::maxdims+1];
            shape[0] = ++elem.nextrow;
            std::copy(info.dim,
                      info.dim+info.ndim,
                      shape+1);

            // resize
            // always in time, maybe in other dimensions
            elem.dset.extend(shape);

            // filespace is hyper from [index,0...] to [index,shape]
            hsize_t start[StateBase::ArrayInfo::maxdims+1];
            start[0] = shape[0]-1;
            std::fill(start+1, start+info.ndim+1, 0);

            shape[0] = 1; // reuse as count
            H5::DataSpace memspace(info.ndim+1, shape);

            H5::DataSpace filespace(elem.dset.getSpace());
            filespace.selectHyperslab(H5S_SELECT_SET, shape, start);

            H5::DataType dtype(elem.dset.getDataType());

            elem.dset.write(info.ptr, dtype, memspace, filespace);

        }
    } CATCH()
}

void H5StateWriter::setAttr(const char *name, const char *val)
{
    try {
        if(H5Aexists(pvt->group.getId(), name)>0)
        //if(pvt->group.attrExists(name)) // H5Aexists was added in 1.8.0, c++ wrapper wasn't added until later...
        {
            pvt->group.removeAttr(name);
        }

        {
            H5::DataSpace scalar;
            H5::StrType dtype(H5::PredType::C_S1, std::max((size_t)16u, strlen(val)));
            H5::Attribute attr(pvt->group.createAttribute(name, dtype, scalar));
            attr.write(dtype, val);
        }
    } CATCH()
}

void H5StateWriter::dontPrint()
{
    try {
        H5::Exception::dontPrint();
    }CATCH()
}
<|endoftext|>


<commit_before>#include "get_stop_times.h"
#include "routing/best_stoptime.h"
#include "type/pb_converter.h"
namespace navitia { namespace timetables {

std::vector<datetime_stop_time> get_stop_times(const std::vector<type::idx_t> &journey_pattern_points, const DateTime &dt,
                                               const DateTime &max_dt,
                                               const size_t max_departures, const type::Data & data, bool disruption_active,
                                               boost::optional<const std::string> calendar_id,
                                               const type::AccessibiliteParams & accessibilite_params) {
    std::vector<datetime_stop_time> result;
    auto test_add = true;

    // Prochain horaire où l’on demandera le prochain départ : on s’en sert pour ne pas obtenir plusieurs fois le même stop_time
    // Initialement, c’est l’heure demandée
    std::map<type::idx_t, DateTime> next_requested_datetime;
    for(auto jpp_idx : journey_pattern_points){
        next_requested_datetime[jpp_idx] = dt;
    }

    while(test_add && result.size() < max_departures) {
        test_add = false;
        for(auto jpp_idx : journey_pattern_points) {
            const type::JourneyPatternPoint* jpp = data.pt_data.journey_pattern_points[jpp_idx];
            if(!jpp->stop_point->accessible(accessibilite_params.properties)) {
                continue;
            }
            auto st = routing::earliest_stop_time(jpp, next_requested_datetime[jpp_idx], data, disruption_active, false, calendar_id, accessibilite_params.vehicle_properties);
            if(st.first != nullptr) {
                DateTime dt_temp = st.second;
                if(dt_temp <= max_dt && result.size() < max_departures) {
                    result.push_back(std::make_pair(dt_temp, st));
                    test_add = true;
                    // Le prochain horaire observé doit être au minimum une seconde après
                    if(st.first->is_frequency()) {
                        DateTimeUtils::update(dt_temp, st.first->end_time);
                    }
                    next_requested_datetime[jpp_idx] = dt_temp + 1;
                }
            }
        }
     }
    std::sort(result.begin(), result.end(),[](datetime_stop_time dst1, datetime_stop_time dst2) {return dst1.first < dst2.first;});

    return result;
}

}} // namespace navitia::timetables
<commit_msg>Buid fix on get_stop_times<commit_after>#include "get_stop_times.h"
#include "routing/best_stoptime.h"
#include "type/pb_converter.h"
namespace navitia { namespace timetables {

std::vector<datetime_stop_time> get_stop_times(const std::vector<type::idx_t> &journey_pattern_points, const DateTime &dt,
                                               const DateTime &max_dt,
                                               const size_t max_departures, const type::Data & data, bool disruption_active,
                                               boost::optional<const std::string> calendar_id,
                                               const type::AccessibiliteParams & accessibilite_params) {
    std::vector<datetime_stop_time> result;
    auto test_add = true;

    // Prochain horaire où l’on demandera le prochain départ : on s’en sert pour ne pas obtenir plusieurs fois le même stop_time
    // Initialement, c’est l’heure demandée
    std::map<type::idx_t, DateTime> next_requested_datetime;
    for(auto jpp_idx : journey_pattern_points){
        next_requested_datetime[jpp_idx] = dt;
    }

    while(test_add && result.size() < max_departures) {
        test_add = false;
        for(auto jpp_idx : journey_pattern_points) {
            const type::JourneyPatternPoint* jpp = data.pt_data.journey_pattern_points[jpp_idx];
            if(!jpp->stop_point->accessible(accessibilite_params.properties)) {
                continue;
            }
            auto st = routing::earliest_stop_time(jpp, next_requested_datetime[jpp_idx], data, disruption_active, false, calendar_id, accessibilite_params.vehicle_properties);
            if(st.first != nullptr) {
                DateTime dt_temp = st.second;
                if(dt_temp <= max_dt && result.size() < max_departures) {
                    result.push_back(std::make_pair(dt_temp, st.first));
                    test_add = true;
                    // Le prochain horaire observé doit être au minimum une seconde après
                    if(st.first->is_frequency()) {
                        DateTimeUtils::update(dt_temp, st.first->end_time);
                    }
                    next_requested_datetime[jpp_idx] = dt_temp + 1;
                }
            }
        }
     }
    std::sort(result.begin(), result.end(),[](datetime_stop_time dst1, datetime_stop_time dst2) {return dst1.first < dst2.first;});

    return result;
}

}} // namespace navitia::timetables
<|endoftext|>


<commit_before>// Copyright (c) 2016 Steinwurf ApS
// All Rights Reserved
//
// Distributed under the "BSD License". See the accompanying LICENSE.rst file.

#pragma once

#include <cassert>
#include <cstdint>
#include <algorithm>
#include <ostream>
#include <iomanip>
#include <string>

namespace hex
{
    /// @brief Small class which wraps a pointer and a size and
    ///        provides an output stream operator to print the content
    ///        as a hexdump.
    ///
    /// The hexdump format consist of three columns per row of
    /// bytes. The first column is the byte offset of the first byte
    /// in the row, the second column is the byte values in hex of
    /// those bytes (16 bytes per row) and the third column is the
    /// ascii representation of those bytes.
    ///
    /// Example of two rows (we removed the middle 6 bytes due to space
    /// limitations):
    ///
    /// @code
    /// 0000  be 40 04 71 45 XXX cd 90 e5 51 31  .@.qE XXX ...Q1
    /// 0010  9d 41 4f 37 05 XXX a9 d5 1e c7 93  .AO7. XXX .....
    /// @endcode
    struct dump
    {
        /// @param data The pointer to the data which we want to dump
        /// @param max_size The maximum size in bytes of the data which we want
        ///        to dump.
        dump(const uint8_t* data, uint32_t max_size) :
            m_data(data),
            m_max_size(max_size),
            m_size(max_size)
        {
            assert(m_data);
            assert(m_max_size);
            assert(m_size);
        }

        /// @param size The size in bytes we wish to dump.
        /// The actual number of bytes dumped will equal the smallest value of
        /// either size or the max_size which was given as a parameter to
        /// the this object's constructor.
        void set_size(uint32_t size)
        {
            assert(m_size > 0);
            m_size = size;
        }

        /// The pointer to the data that should be printed
        const uint8_t* m_data;

        /// The maximum number of bytes that can be printed
        uint32_t m_max_size;

        /// The number of bytes that the user wants to print
        uint32_t m_size;
    };

    /// The actual output operator which prints the data buffer to
    /// the choosen output stream.
    ///
    /// @param out The output stream
    ///
    /// @param hex The hexdump struct initialized with the data and size
    ///        that should be printed
    ///
    /// @return the used output stream
    inline std::ostream& operator<<(std::ostream& out, const dump& hex)
    {
        const uint8_t* data = hex.m_data;
        uint32_t size = std::min(hex.m_size, hex.m_max_size);

        assert(data);
        assert(size > 0);

        // don't change formatting for out
        std::ostream s(out.rdbuf());
        s << std::hex << std::setfill('0');

        std::string buf;
        buf.reserve(17); // premature optimization

        for (uint32_t i = 0; i < size; ++i)
        {
            if ((i % 16) == 0)
            {
                if (i)
                {
                    s << "  " << buf << std::endl;
                    buf.clear();
                }
                s << std::setw(4) << i << ' ';
            }

            uint8_t c = data[i];

            s << ' ' << std::setw(2) << (uint32_t) c;
            buf += (0x20 <= c && c <= 0x7e) ? c : '.';
        }

        if (size % 16)
        {
            // If size if not a multiple of 16 there will be some empty
            // columns in our print out. The remainder i.e. 16 - (size %
            // 16) e.g. for some basic cases:
            //
            // size = 15
            // remainder = 16 - (15 % 16) = 1
            //
            // size = 17
            // remainder = 16 - (17 % 16) = 15
            //
            // and so forth.
            uint32_t remainder = 16 - (size % 16);

            // We add 3 space for each missing character in the output
            s << std::string(3 * remainder, ' ');
        }

        s << "  " << buf << std::endl;

        if (size < hex.m_max_size && 16 < hex.m_max_size)
        {
            uint32_t last_row = (hex.m_max_size / 16) * 16;

            s << "...." << std::endl;
            s << std::setw(4) << last_row << std::endl;
        }

        return out;
    }
}
<commit_msg>No indent for namespaces<commit_after>// Copyright (c) 2016 Steinwurf ApS
// All Rights Reserved
//
// Distributed under the "BSD License". See the accompanying LICENSE.rst file.

#pragma once

#include <cassert>
#include <cstdint>
#include <algorithm>
#include <ostream>
#include <iomanip>
#include <string>

namespace hex
{
/// @brief Small class which wraps a pointer and a size and
///        provides an output stream operator to print the content
///        as a hexdump.
///
/// The hexdump format consist of three columns per row of
/// bytes. The first column is the byte offset of the first byte
/// in the row, the second column is the byte values in hex of
/// those bytes (16 bytes per row) and the third column is the
/// ascii representation of those bytes.
///
/// Example of two rows (we removed the middle 6 bytes due to space
/// limitations):
///
/// @code
/// 0000  be 40 04 71 45 XXX cd 90 e5 51 31  .@.qE XXX ...Q1
/// 0010  9d 41 4f 37 05 XXX a9 d5 1e c7 93  .AO7. XXX .....
/// @endcode
struct dump
{
    /// @param data The pointer to the data which we want to dump
    /// @param max_size The maximum size in bytes of the data which we want
    ///        to dump.
    dump(const uint8_t* data, uint32_t max_size) :
        m_data(data),
        m_max_size(max_size),
        m_size(max_size)
    {
        assert(m_data);
        assert(m_max_size);
        assert(m_size);
    }

    /// @param size The size in bytes we wish to dump.
    /// The actual number of bytes dumped will equal the smallest value of
    /// either size or the max_size which was given as a parameter to
    /// the this object's constructor.
    void set_size(uint32_t size)
    {
        assert(m_size > 0);
        m_size = size;
    }

    /// The pointer to the data that should be printed
    const uint8_t* m_data;

    /// The maximum number of bytes that can be printed
    uint32_t m_max_size;

    /// The number of bytes that the user wants to print
    uint32_t m_size;
};

/// The actual output operator which prints the data buffer to
/// the choosen output stream.
///
/// @param out The output stream
///
/// @param hex The hexdump struct initialized with the data and size
///        that should be printed
///
/// @return the used output stream
inline std::ostream& operator<<(std::ostream& out, const dump& hex)
{
    const uint8_t* data = hex.m_data;
    uint32_t size = std::min(hex.m_size, hex.m_max_size);

    assert(data);
    assert(size > 0);

    // don't change formatting for out
    std::ostream s(out.rdbuf());
    s << std::hex << std::setfill('0');

    std::string buf;
    buf.reserve(17); // premature optimization

    for (uint32_t i = 0; i < size; ++i)
    {
        if ((i % 16) == 0)
        {
            if (i)
            {
                s << "  " << buf << std::endl;
                buf.clear();
            }
            s << std::setw(4) << i << ' ';
        }

        uint8_t c = data[i];

        s << ' ' << std::setw(2) << (uint32_t) c;
        buf += (0x20 <= c && c <= 0x7e) ? c : '.';
    }

    if (size % 16)
    {
        // If size if not a multiple of 16 there will be some empty
        // columns in our print out. The remainder i.e. 16 - (size %
        // 16) e.g. for some basic cases:
        //
        // size = 15
        // remainder = 16 - (15 % 16) = 1
        //
        // size = 17
        // remainder = 16 - (17 % 16) = 15
        //
        // and so forth.
        uint32_t remainder = 16 - (size % 16);

        // We add 3 space for each missing character in the output
        s << std::string(3 * remainder, ' ');
    }

    s << "  " << buf << std::endl;

    if (size < hex.m_max_size && 16 < hex.m_max_size)
    {
        uint32_t last_row = (hex.m_max_size / 16) * 16;

        s << "...." << std::endl;
        s << std::setw(4) << last_row << std::endl;
    }

    return out;
}
}
<|endoftext|>


<commit_before>//===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the generic AliasAnalysis interface which is used as the
// common interface used by all clients and implementations of alias analysis.
//
// This file also implements the default version of the AliasAnalysis interface
// that is to be used when no other implementation is specified.  This does some
// simple tests that detect obvious cases: two different global pointers cannot
// alias, a global cannot alias a malloc, two different mallocs cannot alias,
// etc.
//
// This alias analysis implementation really isn't very good for anything, but
// it is very fast, and makes a nice clean default implementation.  Because it
// handles lots of little corner cases, other, more complex, alias analysis
// implementations may choose to rely on this pass to resolve these simple and
// easy cases.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/Target/TargetData.h"

namespace llvm {

// Register the AliasAnalysis interface, providing a nice name to refer to.
namespace {
  RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
  return alias(L->getOperand(0), TD->getTypeSize(L->getType()),
               P, Size) ? Ref : NoModRef;
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
  // If the stored address cannot alias the pointer in question, then the
  // pointer cannot be modified by the store.
  if (!alias(S->getOperand(1), TD->getTypeSize(S->getOperand(0)->getType()),
             P, Size))
    return NoModRef;

  // If the pointer is a pointer to constant memory, then it could not have been
  // modified by this store.
  return pointsToConstantMemory(P) ? NoModRef : Mod;
}

// AliasAnalysis destructor: DO NOT move this to the header file for
// AliasAnalysis or else clients of the AliasAnalysis class may not depend on
// the AliasAnalysis.o file in the current .a file, causing alias analysis
// support to not be included in the tool correctly!
//
AliasAnalysis::~AliasAnalysis() {}

/// setTargetData - Subclasses must call this method to initialize the
/// AliasAnalysis interface before any other methods are called.
///
void AliasAnalysis::InitializeAliasAnalysis(Pass *P) {
  TD = &P->getAnalysis<TargetData>();
}

// getAnalysisUsage - All alias analysis implementations should invoke this
// directly (using AliasAnalysis::getAnalysisUsage(AU)) to make sure that
// TargetData is required by the pass.
void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<TargetData>();            // All AA's need TargetData.
}

/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
                                        const Value *Ptr, unsigned Size) {
  return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size);
}

/// canInstructionRangeModify - Return true if it is possible for the execution
/// of the specified instructions to modify the value pointed to by Ptr.  The
/// instructions to consider are all of the instructions in the range of [I1,I2]
/// INCLUSIVE.  I1 and I2 must be in the same basic block.
///
bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
                                              const Instruction &I2,
                                              const Value *Ptr, unsigned Size) {
  assert(I1.getParent() == I2.getParent() &&
         "Instructions not in same basic block!");
  BasicBlock::iterator I = const_cast<Instruction*>(&I1);
  BasicBlock::iterator E = const_cast<Instruction*>(&I2);
  ++E;  // Convert from inclusive to exclusive range.

  for (; I != E; ++I) // Check every instruction in range
    if (getModRefInfo(I, const_cast<Value*>(Ptr), Size) & Mod)
      return true;
  return false;
}

// Because of the way .a files work, we must force the BasicAA implementation to
// be pulled in if the AliasAnalysis classes are pulled in.  Otherwise we run
// the risk of AliasAnalysis being used, but the default implementation not
// being linked into the tool that uses it.
//
extern void BasicAAStub();
static IncludeFile INCLUDE_BASICAA_CPP((void*)&BasicAAStub);

namespace {
  struct NoAA : public ImmutablePass, public AliasAnalysis {
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AliasAnalysis::getAnalysisUsage(AU);
    }

    virtual void initializePass() {
      InitializeAliasAnalysis(this);
    }
  };

  // Register this pass...
  RegisterOpt<NoAA>
  X("no-aa", "No Alias Analysis (always returns 'may' alias)");

  // Declare that we implement the AliasAnalysis interface
  RegisterAnalysisGroup<AliasAnalysis, NoAA> Y;
}  // End of anonymous namespace

} // End llvm namespace
<commit_msg>Deinline some virtual methods, provide better mod/ref answers through the use of the boolean queries<commit_after>//===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the generic AliasAnalysis interface which is used as the
// common interface used by all clients and implementations of alias analysis.
//
// This file also implements the default version of the AliasAnalysis interface
// that is to be used when no other implementation is specified.  This does some
// simple tests that detect obvious cases: two different global pointers cannot
// alias, a global cannot alias a malloc, two different mallocs cannot alias,
// etc.
//
// This alias analysis implementation really isn't very good for anything, but
// it is very fast, and makes a nice clean default implementation.  Because it
// handles lots of little corner cases, other, more complex, alias analysis
// implementations may choose to rely on this pass to resolve these simple and
// easy cases.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/Target/TargetData.h"
using namespace llvm;

// Register the AliasAnalysis interface, providing a nice name to refer to.
namespace {
  RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
  return alias(L->getOperand(0), TD->getTypeSize(L->getType()),
               P, Size) ? Ref : NoModRef;
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
  // If the stored address cannot alias the pointer in question, then the
  // pointer cannot be modified by the store.
  if (!alias(S->getOperand(1), TD->getTypeSize(S->getOperand(0)->getType()),
             P, Size))
    return NoModRef;

  // If the pointer is a pointer to constant memory, then it could not have been
  // modified by this store.
  return pointsToConstantMemory(P) ? NoModRef : Mod;
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
  if (Function *F = CS.getCalledFunction())
    if (onlyReadsMemory(F)) {
      if (doesNotAccessMemory(F)) return NoModRef;
      return Ref;
    }

  // If P points to a constant memory location, the call definitely could not
  // modify the memory location.
  return pointsToConstantMemory(P) ? Ref : ModRef;
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
  // FIXME: could probably do better.
  return ModRef;
}

// AliasAnalysis destructor: DO NOT move this to the header file for
// AliasAnalysis or else clients of the AliasAnalysis class may not depend on
// the AliasAnalysis.o file in the current .a file, causing alias analysis
// support to not be included in the tool correctly!
//
AliasAnalysis::~AliasAnalysis() {}

/// setTargetData - Subclasses must call this method to initialize the
/// AliasAnalysis interface before any other methods are called.
///
void AliasAnalysis::InitializeAliasAnalysis(Pass *P) {
  TD = &P->getAnalysis<TargetData>();
}

// getAnalysisUsage - All alias analysis implementations should invoke this
// directly (using AliasAnalysis::getAnalysisUsage(AU)) to make sure that
// TargetData is required by the pass.
void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<TargetData>();            // All AA's need TargetData.
}

/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
                                        const Value *Ptr, unsigned Size) {
  return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size);
}

/// canInstructionRangeModify - Return true if it is possible for the execution
/// of the specified instructions to modify the value pointed to by Ptr.  The
/// instructions to consider are all of the instructions in the range of [I1,I2]
/// INCLUSIVE.  I1 and I2 must be in the same basic block.
///
bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
                                              const Instruction &I2,
                                              const Value *Ptr, unsigned Size) {
  assert(I1.getParent() == I2.getParent() &&
         "Instructions not in same basic block!");
  BasicBlock::iterator I = const_cast<Instruction*>(&I1);
  BasicBlock::iterator E = const_cast<Instruction*>(&I2);
  ++E;  // Convert from inclusive to exclusive range.

  for (; I != E; ++I) // Check every instruction in range
    if (getModRefInfo(I, const_cast<Value*>(Ptr), Size) & Mod)
      return true;
  return false;
}

// Because of the way .a files work, we must force the BasicAA implementation to
// be pulled in if the AliasAnalysis classes are pulled in.  Otherwise we run
// the risk of AliasAnalysis being used, but the default implementation not
// being linked into the tool that uses it.
//
extern void llvm::BasicAAStub();
static IncludeFile INCLUDE_BASICAA_CPP((void*)&BasicAAStub);

namespace {
  struct NoAA : public ImmutablePass, public AliasAnalysis {
    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
      AliasAnalysis::getAnalysisUsage(AU);
    }

    virtual void initializePass() {
      InitializeAliasAnalysis(this);
    }
  };

  // Register this pass...
  RegisterOpt<NoAA>
  X("no-aa", "No Alias Analysis (always returns 'may' alias)");

  // Declare that we implement the AliasAnalysis interface
  RegisterAnalysisGroup<AliasAnalysis, NoAA> Y;
}  // End of anonymous namespace
<|endoftext|>


<commit_before><commit_msg>Bug fix for inline swift zoom sims<commit_after><|endoftext|>