<commit_before>/****************************************************************************
 * Copyright (c) 2012-2018 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 *                                                                          *
 * SPDX-License-Identifier: BSD-3-Clause                                    *
 ****************************************************************************/
/*!
 * \file   tstMapInterface.cpp
 * \author Stuart Slattery
 * \brief  DTK view unit tests.
 */
//---------------------------------------------------------------------------//

#include <DTK_C_API.h>
#include <DTK_DBC.hpp>
#include <DTK_ParallelTraits.hpp>

#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_DefaultMpiComm.hpp>
#include <Teuchos_UnitTestHarness.hpp>

#include <Kokkos_Core.hpp>

#include <memory>

//---------------------------------------------------------------------------//
// User implementation
template <class Space>
struct TestUserData
{
    Kokkos::View<double * [3], Space> coords;
    Kokkos::View<double *, Space> field;

    TestUserData( const int size )
        : coords( "coords", size )
        , field( "field", size )
    {
    }
};

template <class Space>
void nodeListSize( void *user_data, unsigned *space_dim,
                   size_t *local_num_nodes )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    *space_dim = data->coords.extent( 1 );
    *local_num_nodes = data->coords.extent( 0 );
}

template <class Space>
void nodeListData( void *user_data, Coordinate *coords )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    int num_node = data->coords.extent( 0 );
    for ( unsigned n = 0; n < data->coords.extent( 0 ); ++n )
        for ( unsigned d = 0; d < data->coords.extent( 1 ); ++d )
            coords[num_node * d + n] = data->coords( n, d );
}

template <class Space>
void fieldSize( void *user_data, const char *field_name,
                unsigned *field_dimension, size_t *local_num_dofs )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    *field_dimension = 1;
    *local_num_dofs = data->field.extent( 0 );
}

template <class Space>
void pullField( void *user_data, const char *, double *field_dofs )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    for ( unsigned i = 0; i < data->field.extent( 0 ); ++i )
        field_dofs[i] = data->field( i );
}
template <class Space>
void pushField( void *user_data, const char *, const double *field_dofs )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    for ( unsigned i = 0; i < data->field.extent( 0 ); ++i )
        data->field( i ) = field_dofs[i];
}

//---------------------------------------------------------------------------//
// Test execution space enumeration selector.
template <class Space>
struct SpaceSelector;

#if defined( KOKKOS_ENABLE_SERIAL )
template <>
struct SpaceSelector<DataTransferKit::Serial>
{
    static constexpr DTK_ExecutionSpace value() { return DTK_SERIAL; }
};
#endif

#if defined( KOKKOS_ENABLE_OPENMP )
template <>
struct SpaceSelector<DataTransferKit::OpenMP>
{
    static constexpr DTK_ExecutionSpace value() { return DTK_OPENMP; }
};
#endif

#if defined( KOKKOS_ENABLE_SERIAL ) || defined( KOKKOS_ENABLE_OPENMP )
template <>
struct SpaceSelector<DataTransferKit::HostSpace>
{
    static constexpr DTK_MemorySpace value() { return DTK_HOST_SPACE; }
};
#endif

#if defined( KOKKOS_ENABLE_CUDA )
template <>
struct SpaceSelector<DataTransferKit::Cuda>
{
    static constexpr DTK_ExecutionSpace value() { return DTK_CUDA; }
};

template <>
struct SpaceSelector<DataTransferKit::CudaUVMSpace>
{
    static constexpr DTK_MemorySpace value() { return DTK_CUDAUVM_SPACE; }
};
#endif

//---------------------------------------------------------------------------//
// Run the test.
template <class MapSpace, class SourceSpace, class TargetSpace>
void test( bool &success, Teuchos::FancyOStream &out )
{
    // Initialize DTK. The test harness initializes kokkos already.
    DTK_initialize();
    TEST_EQUALITY( errno, DTK_SUCCESS );

    // Check error handling on a bad map.
    DTK_MapHandle bad_handle = nullptr;
    DTK_applyMap( bad_handle, "bad", "bad" );
    TEST_EQUALITY( errno, DTK_INVALID_HANDLE );
    DTK_destroyMap( bad_handle );
    TEST_EQUALITY( errno, DTK_INVALID_HANDLE );

    // Get the communicator
    auto teuchos_comm = Teuchos::DefaultComm<int>::getComm();

    // Create a source and target data set.
    int num_point = 1000;
    auto src_data = std::make_shared<TestUserData<SourceSpace>>( num_point );
    auto tgt_data = std::make_shared<TestUserData<TargetSpace>>( num_point );

    // Assign source and target points and some field data. Make the points
    // the same for now to test the nearest neighbor operator. Invert the rank
    // though so at least they live on different processors.
    int comm_rank = teuchos_comm->getRank();
    int inverse_rank = teuchos_comm->getSize() - comm_rank - 1;
    for ( int p = 0; p < num_point; ++p )
    {
        for ( int d = 0; d < 3; ++d )
        {

            src_data->coords( p, d ) = 1.0 * p + comm_rank * num_point;
            tgt_data->coords( p, d ) = 1.0 * p + inverse_rank * num_point;
        }
        src_data->field( p ) = 1.0 * p + comm_rank * num_point;
        tgt_data->field( p ) = 0.0;
    }

    // Create the source user application instance.
    auto src_handle =
        DTK_createUserApplication( SpaceSelector<SourceSpace>::value() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_NODE_LIST_SIZE_FUNCTION,
                         ( void ( * )() ) & nodeListSize<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_NODE_LIST_DATA_FUNCTION,
                         ( void ( * )() ) & nodeListData<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_FIELD_SIZE_FUNCTION,
                         ( void ( * )() ) & fieldSize<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_PULL_FIELD_DATA_FUNCTION,
                         ( void ( * )() ) & pullField<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );

    // Create the target user application instance.
    auto tgt_handle =
        DTK_createUserApplication( SpaceSelector<TargetSpace>::value() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_NODE_LIST_SIZE_FUNCTION,
                         ( void ( * )() ) & nodeListSize<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_NODE_LIST_DATA_FUNCTION,
                         ( void ( * )() ) & nodeListData<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_FIELD_SIZE_FUNCTION,
                         ( void ( * )() ) & fieldSize<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_PUSH_FIELD_DATA_FUNCTION,
                         ( void ( * )() ) & pushField<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );

    auto comm = Teuchos::getRawMpiComm( *teuchos_comm );

    // Check valid syntax in map create
    for ( std::string const options : {
              R"({ "Map Type": "Nearest Neighbor" })",
              R"({ "Map Type": "NN" })",
              R"({ "Map Type": "Moving Least Squares" })",
              R"({ "Map Type": "MLS" })",
              R"({ "Map Type": "MLS", "Order": "Linear" })",
              R"({ "Map Type": "MLS", "Order": "1" })",
              R"({ "Map Type": "MLS", "Order": 1 })", // doesn't have to be
                                                      // double quoted
              R"({ "Map Type": "MLS", "Order": "Quadratic" })",
              R"({ "Map Type": "MLS", "Order": "2" })",
          } )
    {
        auto map_handle =
            DTK_createMap( SpaceSelector<MapSpace>::value(), comm, src_handle,
                           tgt_handle, options.c_str() );
        TEST_EQUALITY( errno, DTK_SUCCESS );

        DTK_destroyMap( map_handle );
        TEST_EQUALITY( errno, DTK_SUCCESS );
    }

    // Check invalid syntax in map create
    for (
        std::string const options : {
            R"({ "Map Type": "Nearest Neighbor " })", // trailing whitespace
            R"({ "Map Type": "nearest neighbor" })",  // first letter not
                                                      // capitalized
            R"({ "Map Type": "mls" })", // lowercase alias not defined
            R"("Map Type": "Moving Least Squares")",    // missing surrounding
                                                        // curly brackets
            R"({ "Map Type"="Moving Least Squares" })", // equal sign instead
                                                        // of colon
            R"({ "Map Type": "Moving Least Squares"; "hello": "world")", // semicolon
                                                                         // instead
                                                                         // of
                                                                         // comma
            R"({ })",                  // empty JSON object
            R"({ "hello": "world"})",  // "Map Type" is missing
            R"({ "map type": "MLS"})", // first letter not capitalized
        } )
    {
        TEST_THROW( DTK_createMap( SpaceSelector<MapSpace>::value(), comm,
                                   src_handle, tgt_handle, options.c_str() ),
                    DataTransferKit::DataTransferKitException );
    }

    // Check map apply
    for ( std::string const options : {
              R"({ "Map Type": "Nearest Neighbor" })",
              R"({ "Map Type": "Moving Least Squares" })",
          } )
    {
        auto map_handle =
            DTK_createMap( SpaceSelector<MapSpace>::value(), comm, src_handle,
                           tgt_handle, options.c_str() );
        TEST_EQUALITY( errno, DTK_SUCCESS );

        DTK_applyMap( map_handle, "dummy", "dummy" );
        TEST_EQUALITY( errno, DTK_SUCCESS );

        double const relative_tolerance = 1e-14;
        // NOTE adding the same value to both lhs and rhs to resolve floating
        // point comparison issues with zero using Teuchos assertion macro
        double const shift_from_zero = 3.14;
        for ( int p = 0; p < num_point; ++p )
        {
            TEST_FLOATING_EQUALITY( tgt_data->field( p ) + shift_from_zero,
                                    1.0 * p + inverse_rank * num_point +
                                        shift_from_zero,
                                    relative_tolerance );
        }

        DTK_destroyMap( map_handle );
        TEST_EQUALITY( errno, DTK_SUCCESS );
    }

    DTK_destroyUserApplication( src_handle );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_destroyUserApplication( tgt_handle );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_finalize();
    TEST_EQUALITY( errno, DTK_SUCCESS );
}

//---------------------------------------------------------------------------//
// TESTS
//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_SERIAL )
TEUCHOS_UNIT_TEST( MapInterface, Serial )
{
    test<DataTransferKit::Serial, DataTransferKit::HostSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_OPENMP )
TEUCHOS_UNIT_TEST( MapInterface, OpenMP )
{
    test<DataTransferKit::OpenMP, DataTransferKit::HostSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, Cuda )
{
    test<DataTransferKit::Cuda, DataTransferKit::CudaUVMSpace,
         DataTransferKit::CudaUVMSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_SERIAL ) && defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, SerialAndCuda )
{
    test<DataTransferKit::Serial, DataTransferKit::CudaUVMSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::Serial, DataTransferKit::HostSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::Serial, DataTransferKit::CudaUVMSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_OPENMP ) && defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, OpenmpAndCuda )
{
    test<DataTransferKit::OpenMP, DataTransferKit::CudaUVMSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::OpenMP, DataTransferKit::HostSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::OpenMP, DataTransferKit::CudaUVMSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if ( defined( KOKKOS_ENABLE_SERIAL ) || defined( KOKKOS_ENABLE_OPENMP ) ) &&  \
    defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, HostAndCuda )
{
    test<DataTransferKit::Cuda, DataTransferKit::HostSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::Cuda, DataTransferKit::CudaUVMSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
// end tstMapInterface.cpp
//---------------------------------------------------------------------------//
<commit_msg>More tests with invalid options arg to map creation<commit_after>/****************************************************************************
 * Copyright (c) 2012-2018 by the DataTransferKit authors                   *
 * All rights reserved.                                                     *
 *                                                                          *
 * This file is part of the DataTransferKit library. DataTransferKit is     *
 * distributed under a BSD 3-clause license. For the licensing terms see    *
 * the LICENSE file in the top-level directory.                             *
 *                                                                          *
 * SPDX-License-Identifier: BSD-3-Clause                                    *
 ****************************************************************************/
/*!
 * \file   tstMapInterface.cpp
 * \author Stuart Slattery
 * \brief  DTK view unit tests.
 */
//---------------------------------------------------------------------------//

#include <DTK_C_API.h>
#include <DTK_DBC.hpp>
#include <DTK_ParallelTraits.hpp>

#include <Teuchos_DefaultComm.hpp>
#include <Teuchos_DefaultMpiComm.hpp>
#include <Teuchos_UnitTestHarness.hpp>

#include <Kokkos_Core.hpp>

#include <memory>

//---------------------------------------------------------------------------//
// User implementation
template <class Space>
struct TestUserData
{
    Kokkos::View<double * [3], Space> coords;
    Kokkos::View<double *, Space> field;

    TestUserData( const int size )
        : coords( "coords", size )
        , field( "field", size )
    {
    }
};

template <class Space>
void nodeListSize( void *user_data, unsigned *space_dim,
                   size_t *local_num_nodes )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    *space_dim = data->coords.extent( 1 );
    *local_num_nodes = data->coords.extent( 0 );
}

template <class Space>
void nodeListData( void *user_data, Coordinate *coords )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    int num_node = data->coords.extent( 0 );
    for ( unsigned n = 0; n < data->coords.extent( 0 ); ++n )
        for ( unsigned d = 0; d < data->coords.extent( 1 ); ++d )
            coords[num_node * d + n] = data->coords( n, d );
}

template <class Space>
void fieldSize( void *user_data, const char *field_name,
                unsigned *field_dimension, size_t *local_num_dofs )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    *field_dimension = 1;
    *local_num_dofs = data->field.extent( 0 );
}

template <class Space>
void pullField( void *user_data, const char *, double *field_dofs )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    for ( unsigned i = 0; i < data->field.extent( 0 ); ++i )
        field_dofs[i] = data->field( i );
}
template <class Space>
void pushField( void *user_data, const char *, const double *field_dofs )
{
    TestUserData<Space> *data = static_cast<TestUserData<Space> *>( user_data );
    for ( unsigned i = 0; i < data->field.extent( 0 ); ++i )
        data->field( i ) = field_dofs[i];
}

//---------------------------------------------------------------------------//
// Test execution space enumeration selector.
template <class Space>
struct SpaceSelector;

#if defined( KOKKOS_ENABLE_SERIAL )
template <>
struct SpaceSelector<DataTransferKit::Serial>
{
    static constexpr DTK_ExecutionSpace value() { return DTK_SERIAL; }
};
#endif

#if defined( KOKKOS_ENABLE_OPENMP )
template <>
struct SpaceSelector<DataTransferKit::OpenMP>
{
    static constexpr DTK_ExecutionSpace value() { return DTK_OPENMP; }
};
#endif

#if defined( KOKKOS_ENABLE_SERIAL ) || defined( KOKKOS_ENABLE_OPENMP )
template <>
struct SpaceSelector<DataTransferKit::HostSpace>
{
    static constexpr DTK_MemorySpace value() { return DTK_HOST_SPACE; }
};
#endif

#if defined( KOKKOS_ENABLE_CUDA )
template <>
struct SpaceSelector<DataTransferKit::Cuda>
{
    static constexpr DTK_ExecutionSpace value() { return DTK_CUDA; }
};

template <>
struct SpaceSelector<DataTransferKit::CudaUVMSpace>
{
    static constexpr DTK_MemorySpace value() { return DTK_CUDAUVM_SPACE; }
};
#endif

//---------------------------------------------------------------------------//
// Run the test.
template <class MapSpace, class SourceSpace, class TargetSpace>
void test( bool &success, Teuchos::FancyOStream &out )
{
    // Initialize DTK. The test harness initializes kokkos already.
    DTK_initialize();
    TEST_EQUALITY( errno, DTK_SUCCESS );

    // Check error handling on a bad map.
    DTK_MapHandle bad_handle = nullptr;
    DTK_applyMap( bad_handle, "bad", "bad" );
    TEST_EQUALITY( errno, DTK_INVALID_HANDLE );
    DTK_destroyMap( bad_handle );
    TEST_EQUALITY( errno, DTK_INVALID_HANDLE );

    // Get the communicator
    auto teuchos_comm = Teuchos::DefaultComm<int>::getComm();

    // Create a source and target data set.
    int num_point = 1000;
    auto src_data = std::make_shared<TestUserData<SourceSpace>>( num_point );
    auto tgt_data = std::make_shared<TestUserData<TargetSpace>>( num_point );

    // Assign source and target points and some field data. Make the points
    // the same for now to test the nearest neighbor operator. Invert the rank
    // though so at least they live on different processors.
    int comm_rank = teuchos_comm->getRank();
    int inverse_rank = teuchos_comm->getSize() - comm_rank - 1;
    for ( int p = 0; p < num_point; ++p )
    {
        for ( int d = 0; d < 3; ++d )
        {

            src_data->coords( p, d ) = 1.0 * p + comm_rank * num_point;
            tgt_data->coords( p, d ) = 1.0 * p + inverse_rank * num_point;
        }
        src_data->field( p ) = 1.0 * p + comm_rank * num_point;
        tgt_data->field( p ) = 0.0;
    }

    // Create the source user application instance.
    auto src_handle =
        DTK_createUserApplication( SpaceSelector<SourceSpace>::value() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_NODE_LIST_SIZE_FUNCTION,
                         ( void ( * )() ) & nodeListSize<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_NODE_LIST_DATA_FUNCTION,
                         ( void ( * )() ) & nodeListData<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_FIELD_SIZE_FUNCTION,
                         ( void ( * )() ) & fieldSize<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( src_handle, DTK_PULL_FIELD_DATA_FUNCTION,
                         ( void ( * )() ) & pullField<SourceSpace>,
                         src_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );

    // Create the target user application instance.
    auto tgt_handle =
        DTK_createUserApplication( SpaceSelector<TargetSpace>::value() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_NODE_LIST_SIZE_FUNCTION,
                         ( void ( * )() ) & nodeListSize<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_NODE_LIST_DATA_FUNCTION,
                         ( void ( * )() ) & nodeListData<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_FIELD_SIZE_FUNCTION,
                         ( void ( * )() ) & fieldSize<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_setUserFunction( tgt_handle, DTK_PUSH_FIELD_DATA_FUNCTION,
                         ( void ( * )() ) & pushField<TargetSpace>,
                         tgt_data.get() );
    TEST_EQUALITY( errno, DTK_SUCCESS );

    auto comm = Teuchos::getRawMpiComm( *teuchos_comm );

    // Check valid syntax in map create
    for ( std::string const options : {
              R"({ "Map Type": "Nearest Neighbor" })",
              R"({ "Map Type": "NN" })",
              R"({ "Map Type": "Moving Least Squares" })",
              R"({ "Map Type": "MLS" })",
              R"({ "Map Type": "MLS", "Order": "Linear" })",
              R"({ "Map Type": "MLS", "Order": "1" })",
              R"({ "Map Type": "MLS", "Order": 1 })", // doesn't have to be
                                                      // double quoted
              R"({ "Map Type": "MLS", "Order": "Quadratic" })",
              R"({ "Map Type": "MLS", "Order": "2" })",
          } )
    {
        auto map_handle =
            DTK_createMap( SpaceSelector<MapSpace>::value(), comm, src_handle,
                           tgt_handle, options.c_str() );
        TEST_EQUALITY( errno, DTK_SUCCESS );

        DTK_destroyMap( map_handle );
        TEST_EQUALITY( errno, DTK_SUCCESS );
    }

    // Check invalid syntax in map create
    for (
        std::string const options : {
            R"({ "Map Type": "Nearest Neighbor " })", // trailing whitespace
            R"({ "Map Type": "nearest neighbor" })",  // first letter not
                                                      // capitalized
            R"({ "Map Type": "mls" })", // lowercase alias not defined
            R"("Map Type": "Moving Least Squares")",    // missing surrounding
                                                        // curly brackets
            R"({ "Map Type"="Moving Least Squares" })", // equal sign instead
                                                        // of colon
            R"({ "Map Type": "Moving Least Squares"; "hello": "world")", // semicolon
                                                                         // instead
                                                                         // of
                                                                         // comma
            R"({ })",                  // empty JSON object
            R"({ "hello": "world"})",  // "Map Type" is missing
            R"({ "map type": "MLS"})", // first letter not capitalized
            R"({ "Map Type": 3.14 })", // bad data
            R"({ "Map Type": "Is Not Defined Anywhere" })", // invalid value
            R"({ "Map Type": "MLS", "Order": 3 })", // order 3 not available
            R"({ "Map Type": "MLS", "Order": "Invalid" })",
        } )
    {
        TEST_THROW( DTK_createMap( SpaceSelector<MapSpace>::value(), comm,
                                   src_handle, tgt_handle, options.c_str() ),
                    DataTransferKit::DataTransferKitException );
    }

    // Check map apply
    for ( std::string const options : {
              R"({ "Map Type": "Nearest Neighbor" })",
              R"({ "Map Type": "Moving Least Squares" })",
          } )
    {
        auto map_handle =
            DTK_createMap( SpaceSelector<MapSpace>::value(), comm, src_handle,
                           tgt_handle, options.c_str() );
        TEST_EQUALITY( errno, DTK_SUCCESS );

        DTK_applyMap( map_handle, "dummy", "dummy" );
        TEST_EQUALITY( errno, DTK_SUCCESS );

        double const relative_tolerance = 1e-14;
        // NOTE adding the same value to both lhs and rhs to resolve floating
        // point comparison issues with zero using Teuchos assertion macro
        double const shift_from_zero = 3.14;
        for ( int p = 0; p < num_point; ++p )
        {
            TEST_FLOATING_EQUALITY( tgt_data->field( p ) + shift_from_zero,
                                    1.0 * p + inverse_rank * num_point +
                                        shift_from_zero,
                                    relative_tolerance );
        }

        DTK_destroyMap( map_handle );
        TEST_EQUALITY( errno, DTK_SUCCESS );
    }

    DTK_destroyUserApplication( src_handle );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_destroyUserApplication( tgt_handle );
    TEST_EQUALITY( errno, DTK_SUCCESS );
    DTK_finalize();
    TEST_EQUALITY( errno, DTK_SUCCESS );
}

//---------------------------------------------------------------------------//
// TESTS
//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_SERIAL )
TEUCHOS_UNIT_TEST( MapInterface, Serial )
{
    test<DataTransferKit::Serial, DataTransferKit::HostSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_OPENMP )
TEUCHOS_UNIT_TEST( MapInterface, OpenMP )
{
    test<DataTransferKit::OpenMP, DataTransferKit::HostSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, Cuda )
{
    test<DataTransferKit::Cuda, DataTransferKit::CudaUVMSpace,
         DataTransferKit::CudaUVMSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_SERIAL ) && defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, SerialAndCuda )
{
    test<DataTransferKit::Serial, DataTransferKit::CudaUVMSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::Serial, DataTransferKit::HostSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::Serial, DataTransferKit::CudaUVMSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if defined( KOKKOS_ENABLE_OPENMP ) && defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, OpenmpAndCuda )
{
    test<DataTransferKit::OpenMP, DataTransferKit::CudaUVMSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::OpenMP, DataTransferKit::HostSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::OpenMP, DataTransferKit::CudaUVMSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
#if ( defined( KOKKOS_ENABLE_SERIAL ) || defined( KOKKOS_ENABLE_OPENMP ) ) &&  \
    defined( KOKKOS_ENABLE_CUDA )
TEUCHOS_UNIT_TEST( MapInterface, HostAndCuda )
{
    test<DataTransferKit::Cuda, DataTransferKit::HostSpace,
         DataTransferKit::CudaUVMSpace>( success, out );

    test<DataTransferKit::Cuda, DataTransferKit::CudaUVMSpace,
         DataTransferKit::HostSpace>( success, out );
}
#endif

//---------------------------------------------------------------------------//
// end tstMapInterface.cpp
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkPowellOptimizer.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef _itkPowellOptimizer_cxx
#define _itkPowellOptimizer_cxx

#include "itkPowellOptimizer.h"

namespace itk
{

const double POWELL_BRACKET_GOLD = 1.618034;
const double POWELL_BRENT_GOLD = 0.3819660;
const double POWELL_GLIMIT = 100.0;
const double POWELL_TINY = 1.0e-20;

PowellOptimizer
::PowellOptimizer()
{
  m_Maximize = false;

  m_StepLength = 1.0;
  m_StepTolerance = 0.00001;
  m_ValueTolerance = 0.00001;

  m_Stop = false ;

  m_CurrentCost = 0;
  m_CurrentIteration = 0;
  m_CurrentLineIteration = 0;

  m_MaximumIteration = 100 ;

  m_MaximumLineIteration = 100 ;
  m_SpaceDimension = 0;
}

PowellOptimizer
::~PowellOptimizer()
{
}

void
PowellOptimizer
::SetLine(const PowellOptimizer::ParametersType & origin,
          const vnl_vector<double> & direction)
{
  m_LineOrigin = origin;
  m_LineDirection = direction;
  for(unsigned int i=0; i<m_SpaceDimension; i++)
    {
    m_LineDirection[i] = m_LineDirection[i] / this->GetScales()[i];
    }
}

double
PowellOptimizer
::GetLineValue(double x) const
{
  PowellOptimizer::ParametersType xCoord( m_SpaceDimension );
  for(unsigned int i=0; i<m_SpaceDimension; i++)
    {
    xCoord[i] = this->m_LineOrigin[i] + x * this->m_LineDirection[i];
    }
  if(m_Maximize)
    {
    return -(this->m_CostFunction->GetValue(xCoord));
    }
  else
    {
    return this->m_CostFunction->GetValue(xCoord);
    }
}

void
PowellOptimizer
::SetCurrentLinePoint(double x, double fx)
{
  PowellOptimizer::ParametersType xCoord( m_SpaceDimension );
  for(unsigned int i=0; i<m_SpaceDimension; i++)
    {
    xCoord[i] = this->m_LineOrigin[i] + x * this->m_LineDirection[i];
    }
  this->SetCurrentPosition(xCoord);
  if(m_Maximize)
    {
    this->SetCurrentCost(-fx);
    }
  else
    {
    this->SetCurrentCost(fx);
    }
}

void
PowellOptimizer
::Swap(double * a, double  * b) const
{
  double tf;
  tf = *a;
  *a = *b;
  *b = tf;
}

void
PowellOptimizer
::Shift(double *a, double *b, double *c, double d) const
{
  *a = *b;
  *b = *c;
  *c = d;
}

void
PowellOptimizer
::LineBracket(double * ax, double * bx, double * cx,
              double * fa, double * fb, double * fc)
{
  double ulim,u,r,q,fu,dq;

  //*fa = this->GetLineValue(*ax);
  *fb = this->GetLineValue(*bx);
  if (*fb > *fa)
    {
    this->Swap(ax, bx);
    this->Swap(fa, fb);
    }

  *cx = (*bx) + POWELL_BRACKET_GOLD * (*bx - *ax);
  *fc = this->GetLineValue(*cx);
  while (*fb > *fc)
    {
    r = (*bx - *ax) * (*fb - *fc);
    q = (*bx - *cx) * (*fb - *fa);

    dq = q - r;
    if (vcl_abs(dq) < POWELL_TINY)
      {
      dq = vnl_math_sgn(dq) * POWELL_TINY;
      }
    u = (*bx) - ( (*bx - *cx) * q - (*bx - *ax) * r ) / (2.0 * dq);
    ulim = (*bx) + POWELL_GLIMIT * (*cx - *bx);

    if ( (*bx - u) * (u - *cx) > 0.0 )
      {
      fu = this->GetLineValue(u);
      if (fu < *fc)
        {
        *ax = (*bx);
        *bx = u;
        *fa = (*fb);
        *fb = fu;
        return;
        }
      else if (fu > *fb)
        {
        *cx=u;
        *fc=fu;
        return;
        }
      u = (*cx) + POWELL_BRACKET_GOLD * (*cx - *bx);
      fu = this->GetLineValue(u);
      }
    else if ( (*cx - u) * (u - ulim) > 0.0 )
      {
      fu = this->GetLineValue(u);
      if (fu < *fc)
        {
        //SHFT(bx,cx,&u,*cx+GOLD*(*cx-*bx)); awf dumped -- c is useless
        this->Shift(bx, cx, &u, u + POWELL_BRACKET_GOLD * (u - *cx));
        this->Shift(fb, fc, &fu, this->GetLineValue(u));
        }
      }
    else if ( (u - ulim) * (ulim - *cx) >= 0.0)
      {
      u = ulim;
      fu = this->GetLineValue(u);
      }
    else
      {
      u = (*cx) + POWELL_BRACKET_GOLD * (*cx - *bx);
      fu = this->GetLineValue(u);
      }

    this->Shift(ax, bx, cx, u);
    this->Shift(fa, fb, fc, fu);
    }

  this->SetCurrentLinePoint(*bx, *fb);

}

void
PowellOptimizer
::BracketedLineOptimize(double ax, double bx, double cx,
                        double itkNotUsed(fa), double fb, double itkNotUsed(fc),
                        double * extX, double * extVal)
{
  itkWarningMacro("This code has been identified to be covered by the Numerical Recipes copyright. The code will be removed/replaced as soon as possible");
  // For details, please look at:
  //
  // http://www.pit.physik.uni-tuebingen.de/~hehl/CP/brent.c
  //
  // and the discussions on the ITK Wiki:
  //
  // http://www.itk.org/Wiki/Agenda%26Status_022307
  //
  //
  double a, b;
  double d=0.0;
  double etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm;
  double e=0.0;

  a = (ax < cx ? ax : cx);
  b = (ax > cx ? ax : cx);
  x = w = v = bx;
  fw = fv = fx = fb;
  for (m_CurrentLineIteration = 0;
       m_CurrentLineIteration < m_MaximumLineIteration;
       m_CurrentLineIteration++)
    {
    xm = 0.5*(a+b);
    tol1 = m_StepTolerance * vcl_fabs(x) + POWELL_TINY;
    tol2 = 2.0 * tol1;
    if (vcl_fabs(x-xm) <= (tol2 - 0.5*(b-a))
        || 0.5*(b-a) < m_StepTolerance)
      {
      *extX = x;
      *extVal = fx;
      this->SetCurrentLinePoint(x, fx);
      return;
      }
    if (vcl_fabs(e) > tol1)
      {
      r = (x-w) * (fx-fv);
      q = (x-v) * (fx-fw);
      p = (x-v)*q - (x-w)*r;
      q = 2.0 * (q-r);
      if (q > 0.0)
        {
        p = -p;
        }
      q = vcl_fabs(q);
      etemp = e;
      e = d;
      if (vcl_fabs(p) >= vcl_fabs(0.5*q*etemp)
          || p <= q*(a-x)
          || p >= q*(b-x))
        {
        if(x >= xm)
          {
          e = a - x;
          }
        else
          {
          e = b - x;
          }
        d = POWELL_BRENT_GOLD * e;
        }
      else
        {
        d = p/q;
        u = x+d;
        if (u-a < tol2 || b-u < tol2)
          {
          d = tol1 * vnl_math_sgn(xm-x);
          }
        }
      }
    else
      {
      if(x >= xm)
        {
        e = a - x;
        }
      else
        {
        e = b - x;
        }
      d = POWELL_BRENT_GOLD * e;
      }
    if(vcl_fabs(d) >= tol1)
      {
      u = x + d;
      }
    else
      {
      u = x + tol1 * vnl_math_sgn(d);
      }
    fu = this->GetLineValue(u);
    if (fu <= fx)
      {
      if (u >= x)
        {
        a = x;
        }
      else
        {
        b = x;
        }
      this->Shift(&v, &w, &x, u);
      this->Shift(&fv, &fw, &fx, fu);
      }
    else
      {
      if (u < x)
        {
        a = u;
        }
      else
        {
        b = u;
        }
      if (fu <= fw || w == x)
        {
        v = w;
        w = u;
        fv = fw;
        fw = fu;
        }
      else if (fu <= fv || v == x || v == w)
        {
        v = u;
        fv = fu;
        }
      }

    this->SetCurrentLinePoint(x, fx);
    this->InvokeEvent( IterationEvent() );

    }

  *extX = x;
  *extVal = fx;
  this->SetCurrentLinePoint(x, fx);
}

void
PowellOptimizer
::StartOptimization()
{
  if( m_CostFunction.IsNull() )
    {
    return ;
    }

  this->InvokeEvent( StartEvent() );
  m_Stop = false ;

  m_SpaceDimension = m_CostFunction->GetNumberOfParameters();
  m_LineOrigin.set_size(m_SpaceDimension);
  m_LineDirection.set_size(m_SpaceDimension);

  vnl_matrix<double> xi(m_SpaceDimension, m_SpaceDimension);
  vnl_vector<double> xit(m_SpaceDimension);
  xi.set_identity();
  xit.fill(0);
  xit[0] = 1;

  PowellOptimizer::ParametersType p(m_SpaceDimension);
  PowellOptimizer::ParametersType pt(m_SpaceDimension);
  PowellOptimizer::ParametersType ptt(m_SpaceDimension);
  p = this->GetInitialPosition();
  pt = p;

  unsigned int ibig;
  double fp, del, fptt;
  double ax, xx, bx;
  double fa, fx, fb;

  xx = 0;
  this->SetLine(p, xit);
  fx = this->GetLineValue(0);

  for (m_CurrentIteration = 0;
       m_CurrentIteration <= m_MaximumIteration;
       m_CurrentIteration++)
    {
    fp = fx;
    ibig = 0;
    del = 0.0;

    for (unsigned int i = 0; i < m_SpaceDimension; i++)
      {
      for (unsigned int j = 0; j < m_SpaceDimension; ++j)
        {
        xit[j] = xi[j][i];
        }
      fptt = fx;

      this->SetLine(p, xit);

      ax = 0.0;
      fa = fx;
      xx = m_StepLength;
      this->LineBracket(&ax, &xx, &bx, &fa, &fx, &fb);
      this->BracketedLineOptimize(ax, xx, bx, fa, fx, fb, &xx, &fx);
      this->SetCurrentLinePoint(xx, fx);
      p = this->GetCurrentPosition();

      if (vcl_fabs(fptt-fx) > del)
        {
        del = vcl_fabs(fptt-fx);
        ibig = i;
        }
      }

    if (2.0*vcl_fabs(fp-fx)
        <= m_ValueTolerance*(vcl_fabs(fp)+vcl_fabs(fx)))
      {
      this->InvokeEvent( EndEvent() );
      return;
      }

    for (unsigned int j = 0; j < m_SpaceDimension; ++j)
      {
      ptt[j] = 2.0*p[j] - pt[j];
      xit[j] = (p[j] - pt[j]) * this->GetScales()[j];
      pt[j] = p[j];
      }

    this->SetLine(ptt, xit);
    fptt = this->GetLineValue(0);
    if (fptt < fp)
      {
      double t = 2.0 * (fp - 2.0*fx + fptt)
                     * vnl_math_sqr(fp-fx-del)
                     - del * vnl_math_sqr(fp-fptt);
      if (t < 0.0)
        {
        this->SetLine(p, xit);

        ax = 0.0;
        fa = fx;
        xx = 1;
        this->LineBracket(&ax, &xx, &bx, &fa, &fx, &fb);
        this->BracketedLineOptimize(ax, xx, bx, fa, fx, fb, &xx, &fx);
        this->SetCurrentLinePoint(xx, fx);
        p = this->GetCurrentPosition();

        for (unsigned int j = 0; j < m_SpaceDimension; j++)
          {
          xi[j][ibig] = xx * xit[j];
          }
        }
      }

    this->InvokeEvent( IterationEvent() );

    }

  this->InvokeEvent( EndEvent() );

}

/**
 *
 */
void
PowellOptimizer
::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os,indent);

  os << indent << "Space Dimension   " << m_SpaceDimension   << std::endl;
  os << indent << "Maximum Iteration " << m_MaximumIteration << std::endl;
  os << indent << "Current Iteration " << m_CurrentIteration << std::endl;
  os << indent << "Maximize On/Off   " << m_Maximize         << std::endl;
  os << indent << "StepLength        " << m_StepLength       << std::endl;
  os << indent << "StepTolerance     " << m_StepTolerance    << std::endl;
  os << indent << "ValueTolerance    " << m_ValueTolerance   << std::endl;
  os << indent << "LineOrigin        " << m_LineOrigin       << std::endl;
  os << indent << "LineDirection     " << m_LineDirection    << std::endl;
  os << indent << "Current Cost      " << m_CurrentCost      << std::endl;
  os << indent << "Maximum Line Iteration " << m_MaximumLineIteration << std::endl;
  os << indent << "Current Line Iteration " << m_CurrentLineIteration << std::endl;
  os << indent << "Stop              " << m_Stop             << std::endl;
}

} // end of namespace itk
#endif
<commit_msg>BUG: 4546: Replacing Numerical Recipies code from method BracketedLineOptimize      with code from netlib.org. Code adaptation provided by Andinet Enquobahrie.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkPowellOptimizer.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef _itkPowellOptimizer_cxx
#define _itkPowellOptimizer_cxx

#include "itkPowellOptimizer.h"

namespace itk
{

const double POWELL_BRACKET_GOLD = 1.618034;
const double POWELL_BRENT_GOLD = 0.3819660;
const double POWELL_GLIMIT = 100.0;
const double POWELL_TINY = 1.0e-20;

PowellOptimizer
::PowellOptimizer()
{
  m_Maximize = false;

  m_StepLength = 1.0;
  m_StepTolerance = 0.00001;
  m_ValueTolerance = 0.00001;

  m_Stop = false ;

  m_CurrentCost = 0;
  m_CurrentIteration = 0;
  m_CurrentLineIteration = 0;

  m_MaximumIteration = 100 ;

  m_MaximumLineIteration = 100 ;
  m_SpaceDimension = 0;
}

PowellOptimizer
::~PowellOptimizer()
{
}

void
PowellOptimizer
::SetLine(const PowellOptimizer::ParametersType & origin,
          const vnl_vector<double> & direction)
{
  m_LineOrigin = origin;
  m_LineDirection = direction;
  for(unsigned int i=0; i<m_SpaceDimension; i++)
    {
    m_LineDirection[i] = m_LineDirection[i] / this->GetScales()[i];
    }
}

double
PowellOptimizer
::GetLineValue(double x) const
{
  PowellOptimizer::ParametersType xCoord( m_SpaceDimension );
  for(unsigned int i=0; i<m_SpaceDimension; i++)
    {
    xCoord[i] = this->m_LineOrigin[i] + x * this->m_LineDirection[i];
    }
  if(m_Maximize)
    {
    return -(this->m_CostFunction->GetValue(xCoord));
    }
  else
    {
    return this->m_CostFunction->GetValue(xCoord);
    }
}

void
PowellOptimizer
::SetCurrentLinePoint(double x, double fx)
{
  PowellOptimizer::ParametersType xCoord( m_SpaceDimension );
  for(unsigned int i=0; i<m_SpaceDimension; i++)
    {
    xCoord[i] = this->m_LineOrigin[i] + x * this->m_LineDirection[i];
    }
  this->SetCurrentPosition(xCoord);
  if(m_Maximize)
    {
    this->SetCurrentCost(-fx);
    }
  else
    {
    this->SetCurrentCost(fx);
    }
}

void
PowellOptimizer
::Swap(double * a, double  * b) const
{
  double tf;
  tf = *a;
  *a = *b;
  *b = tf;
}

void
PowellOptimizer
::Shift(double *a, double *b, double *c, double d) const
{
  *a = *b;
  *b = *c;
  *c = d;
}

void
PowellOptimizer
::LineBracket(double * ax, double * bx, double * cx,
              double * fa, double * fb, double * fc)
{
  double ulim,u,r,q,fu,dq;

  //*fa = this->GetLineValue(*ax);
  *fb = this->GetLineValue(*bx);
  if (*fb > *fa)
    {
    this->Swap(ax, bx);
    this->Swap(fa, fb);
    }

  *cx = (*bx) + POWELL_BRACKET_GOLD * (*bx - *ax);
  *fc = this->GetLineValue(*cx);
  while (*fb > *fc)
    {
    r = (*bx - *ax) * (*fb - *fc);
    q = (*bx - *cx) * (*fb - *fa);

    dq = q - r;
    if (vcl_abs(dq) < POWELL_TINY)
      {
      dq = vnl_math_sgn(dq) * POWELL_TINY;
      }
    u = (*bx) - ( (*bx - *cx) * q - (*bx - *ax) * r ) / (2.0 * dq);
    ulim = (*bx) + POWELL_GLIMIT * (*cx - *bx);

    if ( (*bx - u) * (u - *cx) > 0.0 )
      {
      fu = this->GetLineValue(u);
      if (fu < *fc)
        {
        *ax = (*bx);
        *bx = u;
        *fa = (*fb);
        *fb = fu;
        return;
        }
      else if (fu > *fb)
        {
        *cx=u;
        *fc=fu;
        return;
        }
      u = (*cx) + POWELL_BRACKET_GOLD * (*cx - *bx);
      fu = this->GetLineValue(u);
      }
    else if ( (*cx - u) * (u - ulim) > 0.0 )
      {
      fu = this->GetLineValue(u);
      if (fu < *fc)
        {
        //SHFT(bx,cx,&u,*cx+GOLD*(*cx-*bx)); awf dumped -- c is useless
        this->Shift(bx, cx, &u, u + POWELL_BRACKET_GOLD * (u - *cx));
        this->Shift(fb, fc, &fu, this->GetLineValue(u));
        }
      }
    else if ( (u - ulim) * (ulim - *cx) >= 0.0)
      {
      u = ulim;
      fu = this->GetLineValue(u);
      }
    else
      {
      u = (*cx) + POWELL_BRACKET_GOLD * (*cx - *bx);
      fu = this->GetLineValue(u);
      }

    this->Shift(ax, bx, cx, u);
    this->Shift(fa, fb, fc, fu);
    }

  this->SetCurrentLinePoint(*bx, *fb);

}

void
PowellOptimizer
::BracketedLineOptimize(double ax, double bx, double cx,
                        double itkNotUsed(fa), double functionValueOfb, double itkNotUsed(fc),
                        double * extX, double * extVal)
{
  double x;
  double v;
  double w;        /* Abscissae, descr. see above  */
  double a;
  double b;

  a = (ax < cx ? ax : cx);
  b = (ax > cx ? ax : cx);

  x = bx;
  w = bx;

  const double goldenSectionRatio = (3.0-sqrt(5.0))/2;  /* Gold section ratio    */

  double functionValueOfX;        /* f(x)        */
  double functionValueOfV;        /* f(v)        */
  double functionValueOfW;        /* f(w)        */

  functionValueOfV   =    functionValueOfb;
  functionValueOfX   =    functionValueOfV;
  functionValueOfW   =    functionValueOfV;

  for (m_CurrentLineIteration = 0;
       m_CurrentLineIteration < m_MaximumLineIteration;
       m_CurrentLineIteration++)
    {

    double range = b-a;      /* Range over which the minimum */
    double middle_range = (a+b)/2;

    double new_step;          /* Step at this iteration       */

    double tolerance1;
    double tolerance2;

    tolerance1 = m_StepTolerance * vcl_fabs(x) + POWELL_TINY;
    tolerance2 = 2.0 * tolerance1;

    if (vcl_fabs(x-middle_range) <= (tolerance2 - 0.5*(b-a))
        || 0.5*(b-a) < m_StepTolerance)
      {
      *extX = x;
      *extVal = functionValueOfX;
      this->SetCurrentLinePoint(x, functionValueOfX);
      return ;        /* Acceptable approx. is found  */
      }

    /* Obtain the gold section step  */
    new_step = goldenSectionRatio * ( x<middle_range ? b-x : a-x );

    /* Decide if the interpolation can be tried  */
    if( fabs(x-w) >= tolerance1  )    /* If x and w are distinct      */
      {
      double t;
      t = (x-w) * (functionValueOfX-functionValueOfV);

      double q;    /* ted as p/q; division operation*/
      q = (x-v) * (functionValueOfX-functionValueOfW);

       double p;     /* Interpolation step is calcula-*/
      p = (x-v)*q - (x-w)*t;

      q = 2*(q-t);

      if( q>(double)0 )    /* q was calculated with the op-*/
        {
        p = -p;      /* posite sign; make q positive  */
        }
      else        /* and assign possible minus to  */
        {
        q = -q;      /* p        */
        }

      /* Chec if x+p/q falls in [a,b] and  not too close to a and b
           and isn't too large */
      if( fabs(p) < fabs(new_step*q) &&
          p > q*(a-x+2*tolerance1) &&
          p < q*(b-x-2*tolerance1)  )
          {
          new_step = p/q;      /* it is accepted         */
          }

      /* If p/q is too large then the  gold section procedure can
         reduce [a,b] range to more  extent      */
      }

     /* Adjust the step to be not less than tolerance*/
    if( fabs(new_step) < tolerance1 )
      {
      if ( new_step > 0.0 )
        {
        new_step = tolerance1;
        }
      else
        {
        new_step = -tolerance1;
        }
      }

    /* Obtain the next approximation to min  */
    /* and reduce the enveloping range  */
    double t = x + new_step;  /* Tentative point for the min  */

    double functionValueOft;

    functionValueOft = this->GetLineValue(t);

    if( functionValueOft <= functionValueOfX )
    {
      if( t < x )      /* Reduce the range so that  */
        {
        b = x;        /* t would fall within it  */
        }
      else
        {
        a = x;
        }

     /* assing the best approximation to x */
    v = w;
    w = x;
    x = t;

    functionValueOfV = functionValueOfW;
    functionValueOfW = functionValueOfX;
    functionValueOfX = functionValueOft;
    }
    else                              /* x remains the better approx  */
    {
    if( t < x )      /* Reduce the range enclosing x  */
      {
      a = t;
      }
    else
      {
      b = t;
      }

      if( functionValueOft <= functionValueOfW || w==x )
        {
        v = w;
        w = t;
        functionValueOfV = functionValueOfW;
        functionValueOfW = functionValueOft;
        }
      else if( functionValueOft<=functionValueOfV || v==x || v==w )
        {
        v = t;
        functionValueOfV=functionValueOft;
        }
     }
  }

  *extX = x;
  *extVal = functionValueOfX;

  this->SetCurrentLinePoint(x, functionValueOfX);

}

void
PowellOptimizer
::StartOptimization()
{
  if( m_CostFunction.IsNull() )
    {
    return ;
    }

  this->InvokeEvent( StartEvent() );
  m_Stop = false ;

  m_SpaceDimension = m_CostFunction->GetNumberOfParameters();
  m_LineOrigin.set_size(m_SpaceDimension);
  m_LineDirection.set_size(m_SpaceDimension);

  vnl_matrix<double> xi(m_SpaceDimension, m_SpaceDimension);
  vnl_vector<double> xit(m_SpaceDimension);
  xi.set_identity();
  xit.fill(0);
  xit[0] = 1;

  PowellOptimizer::ParametersType p(m_SpaceDimension);
  PowellOptimizer::ParametersType pt(m_SpaceDimension);
  PowellOptimizer::ParametersType ptt(m_SpaceDimension);
  p = this->GetInitialPosition();
  pt = p;

  unsigned int ibig;
  double fp, del, fptt;
  double ax, xx, bx;
  double fa, fx, fb;

  xx = 0;
  this->SetLine(p, xit);
  fx = this->GetLineValue(0);

  for (m_CurrentIteration = 0;
       m_CurrentIteration <= m_MaximumIteration;
       m_CurrentIteration++)
    {
    fp = fx;
    ibig = 0;
    del = 0.0;

    for (unsigned int i = 0; i < m_SpaceDimension; i++)
      {
      for (unsigned int j = 0; j < m_SpaceDimension; ++j)
        {
        xit[j] = xi[j][i];
        }
      fptt = fx;

      this->SetLine(p, xit);

      ax = 0.0;
      fa = fx;
      xx = m_StepLength;
      this->LineBracket(&ax, &xx, &bx, &fa, &fx, &fb);
      this->BracketedLineOptimize(ax, xx, bx, fa, fx, fb, &xx, &fx);
      this->SetCurrentLinePoint(xx, fx);
      p = this->GetCurrentPosition();

      if (vcl_fabs(fptt-fx) > del)
        {
        del = vcl_fabs(fptt-fx);
        ibig = i;
        }
      }

    if (2.0*vcl_fabs(fp-fx)
        <= m_ValueTolerance*(vcl_fabs(fp)+vcl_fabs(fx)))
      {
      this->InvokeEvent( EndEvent() );
      return;
      }

    for (unsigned int j = 0; j < m_SpaceDimension; ++j)
      {
      ptt[j] = 2.0*p[j] - pt[j];
      xit[j] = (p[j] - pt[j]) * this->GetScales()[j];
      pt[j] = p[j];
      }

    this->SetLine(ptt, xit);
    fptt = this->GetLineValue(0);
    if (fptt < fp)
      {
      double t = 2.0 * (fp - 2.0*fx + fptt)
                     * vnl_math_sqr(fp-fx-del)
                     - del * vnl_math_sqr(fp-fptt);
      if (t < 0.0)
        {
        this->SetLine(p, xit);

        ax = 0.0;
        fa = fx;
        xx = 1;
        this->LineBracket(&ax, &xx, &bx, &fa, &fx, &fb);
        this->BracketedLineOptimize(ax, xx, bx, fa, fx, fb, &xx, &fx);
        this->SetCurrentLinePoint(xx, fx);
        p = this->GetCurrentPosition();

        for (unsigned int j = 0; j < m_SpaceDimension; j++)
          {
          xi[j][ibig] = xx * xit[j];
          }
        }
      }

    this->InvokeEvent( IterationEvent() );

    }

  this->InvokeEvent( EndEvent() );

}

/**
 *
 */
void
PowellOptimizer
::PrintSelf(std::ostream& os, Indent indent) const
{
  Superclass::PrintSelf(os,indent);

  os << indent << "Space Dimension   " << m_SpaceDimension   << std::endl;
  os << indent << "Maximum Iteration " << m_MaximumIteration << std::endl;
  os << indent << "Current Iteration " << m_CurrentIteration << std::endl;
  os << indent << "Maximize On/Off   " << m_Maximize         << std::endl;
  os << indent << "StepLength        " << m_StepLength       << std::endl;
  os << indent << "StepTolerance     " << m_StepTolerance    << std::endl;
  os << indent << "ValueTolerance    " << m_ValueTolerance   << std::endl;
  os << indent << "LineOrigin        " << m_LineOrigin       << std::endl;
  os << indent << "LineDirection     " << m_LineDirection    << std::endl;
  os << indent << "Current Cost      " << m_CurrentCost      << std::endl;
  os << indent << "Maximum Line Iteration " << m_MaximumLineIteration << std::endl;
  os << indent << "Current Line Iteration " << m_CurrentLineIteration << std::endl;
  os << indent << "Stop              " << m_Stop             << std::endl;
}

} // end of namespace itk
#endif
<|endoftext|>


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

// This include needs to be the very first to prevent problems with warnings
// regarding redefinition of _POSIX_C_SOURCE
#include "boost/python.hpp"

#include "IECore/Renderer.h"
#include "IECore/CompoundObject.h"
#include "IECore/CompoundParameter.h"
#include "IECore/MessageHandler.h"
#include "IECore/ParameterisedProcedural.h"
#include "IECore/bindings/ParameterisedProceduralBinding.h"
#include "IECore/bindings/RunTimeTypedBinding.h"
#include "IECore/bindings/Wrapper.h"

using namespace boost::python;

namespace IECore
{

class ParameterisedProceduralWrap : public ParameterisedProcedural, public Wrapper<ParameterisedProcedural>
{

	public :
/*
		ParameterisedProceduralWrap( PyObject *self )
			: ParameterisedProcedural(), Wrapper<ParameterisedProcedural>( self, this )
		{
		}
*/
		ParameterisedProceduralWrap( PyObject *self, const std::string &description="" )
			: ParameterisedProcedural( description ), Wrapper<ParameterisedProcedural>( self, this )
		{
		}

		virtual void doRenderState( RendererPtr renderer, ConstCompoundObjectPtr args ) const
		{
			try
			{
				override o = this->get_override( "doRenderState" );
				if( o )
				{
					o( renderer, boost::const_pointer_cast<CompoundObject>( args ) );
				}
				else
				{
					ParameterisedProcedural::doRenderState( renderer, args );
				}
			}
			catch( error_already_set )
			{
				PyErr_Print();
			}
			catch( const std::exception &e )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRenderState", e.what() );
			}
			catch( ... )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRenderState", "Caught unknown exception" );
			}

		}

		virtual Imath::Box3f doBound( ConstCompoundObjectPtr args ) const
		{
			try
			{
				override o = this->get_override( "doBound" );
				if( o )
				{
					return o( boost::const_pointer_cast<CompoundObject>( args ) );
				}
				else
				{
					msg( Msg::Error, "ParameterisedProceduralWrap::doBound", "doBound() python method not defined" );
				}
			}
			catch( error_already_set )
			{
				PyErr_Print();
			}
			catch( const std::exception &e )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doBound", e.what() );
			}
			catch( ... )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doBound", "Caught unknown exception" );
			}
			return Imath::Box3f(); // empty
		}

		virtual void doRender( RendererPtr r, ConstCompoundObjectPtr args ) const
		{
			// ideally we might not do any exception handling here, and always leave it to the host.
			// but in our case the host is mainly 3delight and that does no exception handling at all.
			try
			{
				override o = this->get_override( "doRender" );
				if( o )
				{
					o( r, boost::const_pointer_cast<CompoundObject>( args ) );
				}
				else
				{
					msg( Msg::Error, "ParameterisedProceduralWrap::doRender", "doRender() python method not defined" );
				}
			}
			catch( error_already_set )
			{
				PyErr_Print();
			}
			catch( const std::exception &e )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRender", e.what() );
			}
			catch( ... )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRender", "Caught unknown exception" );
			}
		}

		IE_COREPYTHON_RUNTIMETYPEDWRAPPERFNS( ParameterisedProcedural );

};

IE_CORE_DECLAREPTR( ParameterisedProceduralWrap );

static ParameterPtr parameterisedProceduralGetItem( ParameterisedProcedural &o, const std::string &n )
{
	ParameterPtr p = o.parameters()->parameter<Parameter>( n );
	if( !p )
	{
		throw Exception( std::string("Parameter ") + n + " doesn't exist" );
	}
	return p;
}

void bindParameterisedProcedural()
{

	RunTimeTypedClass<ParameterisedProcedural, ParameterisedProceduralWrapPtr>()
		.def( init<>() )
		.def( init< const std::string >( arg( "description") ) )
		.add_property( "description", make_function( &ParameterisedProcedural::description, return_value_policy<copy_const_reference>() ) )
		.def( "parameters", (CompoundParameterPtr (ParameterisedProcedural::*)())&ParameterisedProcedural::parameters )
		.def( "render", (void (ParameterisedProcedural::*)( RendererPtr ) const )&ParameterisedProcedural::render )
		.def( "render", (void (ParameterisedProcedural::*)( RendererPtr, bool, bool, bool, bool ) const )&ParameterisedProcedural::render, ( arg( "renderer" ), arg( "inAttributeBlock" ) = true, arg( "withState" ) = true, arg( "withGeometry" ) = true, arg( "immediateGeometry" ) = false ) )
		.def( "__getitem__", &parameterisedProceduralGetItem )
	;

}

} // namespace IECore
<commit_msg>removed old code<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2009, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

// This include needs to be the very first to prevent problems with warnings
// regarding redefinition of _POSIX_C_SOURCE
#include "boost/python.hpp"

#include "IECore/Renderer.h"
#include "IECore/CompoundObject.h"
#include "IECore/CompoundParameter.h"
#include "IECore/MessageHandler.h"
#include "IECore/ParameterisedProcedural.h"
#include "IECore/bindings/ParameterisedProceduralBinding.h"
#include "IECore/bindings/RunTimeTypedBinding.h"
#include "IECore/bindings/Wrapper.h"

using namespace boost::python;

namespace IECore
{

class ParameterisedProceduralWrap : public ParameterisedProcedural, public Wrapper<ParameterisedProcedural>
{

	public :

		ParameterisedProceduralWrap( PyObject *self, const std::string &description="" )
			: ParameterisedProcedural( description ), Wrapper<ParameterisedProcedural>( self, this )
		{
		}

		virtual void doRenderState( RendererPtr renderer, ConstCompoundObjectPtr args ) const
		{
			try
			{
				override o = this->get_override( "doRenderState" );
				if( o )
				{
					o( renderer, boost::const_pointer_cast<CompoundObject>( args ) );
				}
				else
				{
					ParameterisedProcedural::doRenderState( renderer, args );
				}
			}
			catch( error_already_set )
			{
				PyErr_Print();
			}
			catch( const std::exception &e )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRenderState", e.what() );
			}
			catch( ... )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRenderState", "Caught unknown exception" );
			}

		}

		virtual Imath::Box3f doBound( ConstCompoundObjectPtr args ) const
		{
			try
			{
				override o = this->get_override( "doBound" );
				if( o )
				{
					return o( boost::const_pointer_cast<CompoundObject>( args ) );
				}
				else
				{
					msg( Msg::Error, "ParameterisedProceduralWrap::doBound", "doBound() python method not defined" );
				}
			}
			catch( error_already_set )
			{
				PyErr_Print();
			}
			catch( const std::exception &e )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doBound", e.what() );
			}
			catch( ... )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doBound", "Caught unknown exception" );
			}
			return Imath::Box3f(); // empty
		}

		virtual void doRender( RendererPtr r, ConstCompoundObjectPtr args ) const
		{
			// ideally we might not do any exception handling here, and always leave it to the host.
			// but in our case the host is mainly 3delight and that does no exception handling at all.
			try
			{
				override o = this->get_override( "doRender" );
				if( o )
				{
					o( r, boost::const_pointer_cast<CompoundObject>( args ) );
				}
				else
				{
					msg( Msg::Error, "ParameterisedProceduralWrap::doRender", "doRender() python method not defined" );
				}
			}
			catch( error_already_set )
			{
				PyErr_Print();
			}
			catch( const std::exception &e )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRender", e.what() );
			}
			catch( ... )
			{
				msg( Msg::Error, "ParameterisedProceduralWrap::doRender", "Caught unknown exception" );
			}
		}

		IE_COREPYTHON_RUNTIMETYPEDWRAPPERFNS( ParameterisedProcedural );

};

IE_CORE_DECLAREPTR( ParameterisedProceduralWrap );

static ParameterPtr parameterisedProceduralGetItem( ParameterisedProcedural &o, const std::string &n )
{
	ParameterPtr p = o.parameters()->parameter<Parameter>( n );
	if( !p )
	{
		throw Exception( std::string("Parameter ") + n + " doesn't exist" );
	}
	return p;
}

void bindParameterisedProcedural()
{

	RunTimeTypedClass<ParameterisedProcedural, ParameterisedProceduralWrapPtr>()
		.def( init<>() )
		.def( init< const std::string >( arg( "description") ) )
		.add_property( "description", make_function( &ParameterisedProcedural::description, return_value_policy<copy_const_reference>() ) )
		.def( "parameters", (CompoundParameterPtr (ParameterisedProcedural::*)())&ParameterisedProcedural::parameters )
		.def( "render", (void (ParameterisedProcedural::*)( RendererPtr ) const )&ParameterisedProcedural::render )
		.def( "render", (void (ParameterisedProcedural::*)( RendererPtr, bool, bool, bool, bool ) const )&ParameterisedProcedural::render, ( arg( "renderer" ), arg( "inAttributeBlock" ) = true, arg( "withState" ) = true, arg( "withGeometry" ) = true, arg( "immediateGeometry" ) = false ) )
		.def( "__getitem__", &parameterisedProceduralGetItem )
	;

}

} // namespace IECore
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

bool hasUppercase(const string& str)
{
    for (auto c : str)
        if (isupper(c)) return true;
    return false;
}

void makeLowercase(string& str)
{
    for (auto& c : str)
        if (isupper(c)) c = tolower(c);
}

int main()
{
    string str("Hello World!");
    cout << hasUppercase(str) << endl;
    makeLowercase(str);
    cout << str << endl;

    return 0;
}
<commit_msg>improving #82<commit_after>#include <iostream>
#include <string>

using std::string;

bool hasUppercase(const string& str)
{
    for (auto c : str)
        if (isupper(c)) return true;
    return false;
}

const string& makeLowercase(string& str)
{
    for (auto& c : str)
        if (isupper(c)) c = tolower(c);
    return str;
}

int main()
{
    string str("Hello World!");
    std::cout << std::boolalpha << hasUppercase(str) << std::endl;
    std::cout << makeLowercase(str) << std::endl;
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
//!
//! \file   tstGeneralEstimatorDimensionDiscretization.cpp
//! \author Alex Robinson
//! \brief  General estimator dimension discretization unit tests
//!
//---------------------------------------------------------------------------//

// Std Lib Includes
#include <iostream>

// Trilinos Includes
#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_Array.hpp>
#include <Teuchos_RCP.hpp>

// FRENSIE Includes
#include "MonteCarlo_GeneralEstimatorDimensionDiscretization.hpp"
#include "MonteCarlo_PhaseSpaceDimensionTraits.hpp"
#include "MonteCarlo_UnitTestHarnessExtensions.hpp"

//---------------------------------------------------------------------------//
// Instantiation Macros.
//---------------------------------------------------------------------------//
#define UNIT_TEST_INSTANTIATION( type, name )				\
  using namespace MonteCarlo;						\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, ENERGY_DIMENSION )	\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, COSINE_DIMENSION )	\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, TIME_DIMENSION )	\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, COLLISION_NUMBER_DIMENSION ) \

//---------------------------------------------------------------------------//
// Testing Functions.
//---------------------------------------------------------------------------//
// Initialize an estimator dimension discretization pointer
template<MonteCarlo::PhaseSpaceDimension dimension>
void initialize( Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization>&
		 dimension_discretization,
		 const bool add_discrete_lines )
{
  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  Teuchos::Array<typename EPSDT::dimensionType> discretization( 4 );

  if( add_discrete_lines )
    discretization.resize( 9 );

  discretization[0] = 0.0;
  discretization[1] = 1e-5;
  discretization[2] = 1e-4;
  discretization[3] = 1e-3;

  if( add_discrete_lines )
  {
    discretization[4] = 1e-3;
    discretization[5] = 1e-2;
    discretization[6] = 1e-1;
    discretization[7] = 1e-1;
    discretization[8] = 1.0;
  }

  dimension_discretization.reset(
                new MonteCarlo::GeneralEstimatorDimensionDiscretization<dimension>(
							    discretization ) );
}

// Initialize an estimator dimension discretization point
template<>
void initialize<MonteCarlo::COLLISION_NUMBER_DIMENSION>(
			Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization>&
			dimension_discretization,
			const bool )
{
  typedef MonteCarlo::PhaseSpaceDimensionTraits<MonteCarlo::COLLISION_NUMBER_DIMENSION> EPSDT;

  Teuchos::Array<typename EPSDT::dimensionType> discretization( 3 );

  discretization[0] = 0;
  discretization[1] = 1;
  discretization[2] = std::numeric_limits<unsigned>::max();

  dimension_discretization.reset( new MonteCarlo::GeneralEstimatorDimensionDiscretization<MonteCarlo::COLLISION_NUMBER_DIMENSION>( discretization ) );
}

//---------------------------------------------------------------------------//
// Tests.
//---------------------------------------------------------------------------//
// Check that the discretized dimension can be returned
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   getDimension,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, false );

  TEST_EQUALITY_CONST( discretized_dimension->getDimension(),
		       dimension );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 getDimension );

//---------------------------------------------------------------------------//
// Check that the number of bins can be returned
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   getNumberOfBins,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, false );

  TEST_EQUALITY_CONST( discretized_dimension->getNumberOfBins(), 3u );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 getNumberOfBins );

//---------------------------------------------------------------------------//
// Check if a value is contained in the discretization
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   isValueInDiscretization,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, false );

  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  typename EPSDT::dimensionType value_1, value_2, value_3, value_4;

  if( dimension != MonteCarlo::COLLISION_NUMBER_DIMENSION )
  {
    value_1 = -1;
    value_2 = 0;
    value_3 = 1e-3;
    value_4 = 1e-2;
    TEST_ASSERT( !discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_1 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_2 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_3 ) ) );
    TEST_ASSERT( !discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_4 ) ) );
  }
  else
  {
    value_1 = 0;
    value_2 = 1;
    value_3 = 2;
    value_3 = -1; // max value
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_1 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_2 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_3 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_4 ) ) );
  }
 }

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 isValueInDiscretization );

//---------------------------------------------------------------------------//
// Check that a bin index can be calculated
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   calculateBinIndex,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, true );

  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  typename EPSDT::dimensionType value_1, value_2, value_3, value_4,
    value_5, value_6, value_7, value_8, value_9, value_10, value_11,
    value_12, value_13, value_14, value_15, value_16, value_17;

  if( dimension != MonteCarlo::COLLISION_NUMBER_DIMENSION )
  {
    value_1 = 0.0;
    value_2 = 5e-6;
    value_3 = 1e-5;
    value_4 = 5e-5;
    value_5 = 1e-4;
    value_6 = 5e-4;
    value_7 = 9.9999999999999e-4;
    value_8 = 1e-3;
    value_9 = 1.0000000000001e-3;
    value_10 = 5e-3;
    value_11 = 1e-2;
    value_12 = 5e-2;
    value_13 = 9.999999999999e-2;
    value_14 = 1e-1;
    value_15 = 1.000000000001e-1;
    value_16 = 5e-1;
    value_17 = 1.0;

    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_1 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_2 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_3 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_4 ) ), 1u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_5 ) ), 1u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_6 ) ), 2u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_7 ) ), 2u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_8 ) ), 3u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_9 ) ), 4u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_10 ) ), 4u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_11 ) ), 4u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_12 ) ), 5u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_13 ) ), 5u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_14 ) ), 6u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_15 ) ), 7u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_16 ) ), 7u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_17 ) ), 7u );
  }
  else
  {
    value_1 = 0;
    value_2 = 1;
    value_3 = 2;
    value_4 = -1; // max value

    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_1 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_2 ) ), 1u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_3 ) ), 2u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_4 ) ), 2u );
  }

  discretized_dimension->print( std::cout );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 calculateBinIndex );

//---------------------------------------------------------------------------//
// end tstGeneralEstimatorDimensionDiscretization.cpp
//---------------------------------------------------------------------------//

<commit_msg>Finished test the exportData member function in the estimator dimension discretization classes.<commit_after>//---------------------------------------------------------------------------//
//!
//! \file   tstGeneralEstimatorDimensionDiscretization.cpp
//! \author Alex Robinson
//! \brief  General estimator dimension discretization unit tests
//!
//---------------------------------------------------------------------------//

// Std Lib Includes
#include <iostream>
#include <sstream>

// Trilinos Includes
#include <Teuchos_UnitTestHarness.hpp>
#include <Teuchos_Array.hpp>
#include <Teuchos_RCP.hpp>

// FRENSIE Includes
#include "MonteCarlo_GeneralEstimatorDimensionDiscretization.hpp"
#include "MonteCarlo_PhaseSpaceDimensionTraits.hpp"
#include "MonteCarlo_EstimatorHDF5FileHandler.hpp"
#include "MonteCarlo_UnitTestHarnessExtensions.hpp"

//---------------------------------------------------------------------------//
// Instantiation Macros.
//---------------------------------------------------------------------------//
#define UNIT_TEST_INSTANTIATION( type, name )				\
  using namespace MonteCarlo;						\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, ENERGY_DIMENSION )	\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, COSINE_DIMENSION )	\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, TIME_DIMENSION )	\
  TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( type, name, COLLISION_NUMBER_DIMENSION ) \

//---------------------------------------------------------------------------//
// Testing Functions.
//---------------------------------------------------------------------------//
// Initialize an estimator dimension discretization pointer
template<MonteCarlo::PhaseSpaceDimension dimension>
void initialize( Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization>&
		 dimension_discretization,
		 const bool add_discrete_lines )
{
  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  Teuchos::Array<typename EPSDT::dimensionType> discretization( 4 );

  if( add_discrete_lines )
    discretization.resize( 9 );

  discretization[0] = 0.0;
  discretization[1] = 1e-5;
  discretization[2] = 1e-4;
  discretization[3] = 1e-3;

  if( add_discrete_lines )
  {
    discretization[4] = 1e-3;
    discretization[5] = 1e-2;
    discretization[6] = 1e-1;
    discretization[7] = 1e-1;
    discretization[8] = 1.0;
  }

  dimension_discretization.reset(
                new MonteCarlo::GeneralEstimatorDimensionDiscretization<dimension>(
							    discretization ) );
}

// Initialize an estimator dimension discretization point
template<>
void initialize<MonteCarlo::COLLISION_NUMBER_DIMENSION>(
			Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization>&
			dimension_discretization,
			const bool )
{
  typedef MonteCarlo::PhaseSpaceDimensionTraits<MonteCarlo::COLLISION_NUMBER_DIMENSION> EPSDT;

  Teuchos::Array<typename EPSDT::dimensionType> discretization( 3 );

  discretization[0] = 0;
  discretization[1] = 1;
  discretization[2] = std::numeric_limits<unsigned>::max();

  dimension_discretization.reset( new MonteCarlo::GeneralEstimatorDimensionDiscretization<MonteCarlo::COLLISION_NUMBER_DIMENSION>( discretization ) );
}

//---------------------------------------------------------------------------//
// Tests.
//---------------------------------------------------------------------------//
// Check that the discretized dimension can be returned
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   getDimension,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, false );

  TEST_EQUALITY_CONST( discretized_dimension->getDimension(),
		       dimension );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 getDimension );

//---------------------------------------------------------------------------//
// Check that the number of bins can be returned
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   getNumberOfBins,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, false );

  TEST_EQUALITY_CONST( discretized_dimension->getNumberOfBins(), 3u );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 getNumberOfBins );

//---------------------------------------------------------------------------//
// Check if a value is contained in the discretization
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   isValueInDiscretization,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, false );

  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  typename EPSDT::dimensionType value_1, value_2, value_3, value_4;

  if( dimension != MonteCarlo::COLLISION_NUMBER_DIMENSION )
  {
    value_1 = -1;
    value_2 = 0;
    value_3 = 1e-3;
    value_4 = 1e-2;
    TEST_ASSERT( !discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_1 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_2 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_3 ) ) );
    TEST_ASSERT( !discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_4 ) ) );
  }
  else
  {
    value_1 = 0;
    value_2 = 1;
    value_3 = 2;
    value_3 = -1; // max value
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_1 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_2 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_3 ) ) );
    TEST_ASSERT( discretized_dimension->isValueInDiscretization(
						   Teuchos::any( value_4 ) ) );
  }
 }

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 isValueInDiscretization );

//---------------------------------------------------------------------------//
// Check that a bin index can be calculated
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   calculateBinIndex,
				   dimension )
{
  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization> discretized_dimension;

  initialize<dimension>( discretized_dimension, true );

  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  typename EPSDT::dimensionType value_1, value_2, value_3, value_4,
    value_5, value_6, value_7, value_8, value_9, value_10, value_11,
    value_12, value_13, value_14, value_15, value_16, value_17;

  if( dimension != MonteCarlo::COLLISION_NUMBER_DIMENSION )
  {
    value_1 = 0.0;
    value_2 = 5e-6;
    value_3 = 1e-5;
    value_4 = 5e-5;
    value_5 = 1e-4;
    value_6 = 5e-4;
    value_7 = 9.9999999999999e-4;
    value_8 = 1e-3;
    value_9 = 1.0000000000001e-3;
    value_10 = 5e-3;
    value_11 = 1e-2;
    value_12 = 5e-2;
    value_13 = 9.999999999999e-2;
    value_14 = 1e-1;
    value_15 = 1.000000000001e-1;
    value_16 = 5e-1;
    value_17 = 1.0;

    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_1 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_2 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_3 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_4 ) ), 1u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_5 ) ), 1u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_6 ) ), 2u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_7 ) ), 2u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_8 ) ), 3u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_9 ) ), 4u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_10 ) ), 4u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_11 ) ), 4u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_12 ) ), 5u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_13 ) ), 5u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_14 ) ), 6u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_15 ) ), 7u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_16 ) ), 7u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					      Teuchos::any( value_17 ) ), 7u );
  }
  else
  {
    value_1 = 0;
    value_2 = 1;
    value_3 = 2;
    value_4 = -1; // max value

    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_1 ) ), 0u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_2 ) ), 1u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_3 ) ), 2u );
    TEST_EQUALITY_CONST( discretized_dimension->calculateBinIndex(
					       Teuchos::any( value_4 ) ), 2u );
  }

  discretized_dimension->print( std::cout );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 calculateBinIndex );

//---------------------------------------------------------------------------//
// Check that the bin boundaries can be exported
MC_UNIT_TEST_EPSD_TEMPLATE_1_DECL( GeneralEstimatorDimensionDiscretization,
				   exportData,
				   dimension )
{
  // Set up the discretization
  typedef MonteCarlo::PhaseSpaceDimensionTraits<dimension> EPSDT;

  Teuchos::Array<typename EPSDT::dimensionType> discretization;

  if( dimension != MonteCarlo::COLLISION_NUMBER_DIMENSION )
  {
    discretization.resize( 9 );

    discretization[0] = 0.0;
    discretization[1] = 1e-5;
    discretization[2] = 1e-4;
    discretization[3] = 1e-3;
    discretization[4] = 1e-3;
    discretization[5] = 1e-2;
    discretization[6] = 1e-1;
    discretization[7] = 1e-1;
    discretization[8] = 1.0;
  }
  else
  {
    discretization.resize( 4 );

    discretization[0] = 0u;
    discretization[1] = 1u;
    discretization[2] = 2u;
    discretization[3] = std::numeric_limits<unsigned>::max();
  }

  Teuchos::RCP<MonteCarlo::EstimatorDimensionDiscretization>
    discretized_dimension(
            new MonteCarlo::GeneralEstimatorDimensionDiscretization<dimension>(
							    discretization ) );

  // Set up the EstimatorHDF5FileHandler
  std::ostringstream oss;
  oss << dimension << ".h5";

  MonteCarlo::EstimatorHDF5FileHandler hdf5_file_handler( oss.str() );

  discretized_dimension->exportData( 0u, hdf5_file_handler );
  discretized_dimension->exportData( 10u, hdf5_file_handler );

  // Make sure the data was written to the correct estimators
  Teuchos::Array<typename EPSDT::dimensionType> discretization_copy;

  hdf5_file_handler.getEstimatorBinBoundaries<dimension>( 0u,
							  discretization_copy);

  TEST_COMPARE_ARRAYS( discretization, discretization_copy );

  hdf5_file_handler.getEstimatorBinBoundaries<dimension>( 10u,
							  discretization_copy);

  TEST_COMPARE_ARRAYS( discretization, discretization_copy );

  TEST_THROW( hdf5_file_handler.getEstimatorBinBoundaries<dimension>(
							 1u,
							 discretization_copy ),
	      std::runtime_error );
}

UNIT_TEST_INSTANTIATION( GeneralEstimatorDimensionDiscretization,
			 exportData );

//---------------------------------------------------------------------------//
// end tstGeneralEstimatorDimensionDiscretization.cpp
//---------------------------------------------------------------------------//

<|endoftext|>


<commit_before>//! @Alan @pezy
//!
//! Exercise 9.14:
//! Write a program to assign the elements from a list of char* pointers
//! to C-style character strings
//!
//! @Notice C-style character strings should use const char*, otherwise warning.
//!

#include <iostream>
#include <string>
#include <vector>
#include <list>

int main()
{
    std::list<const char*> l{"Mooophy", "pezy", "Queeuqueg"};
    std::vector<std::string> v;
    v.assign(l.cbegin(), l.cend());

    for (const auto& ch : v) std::cout << ch << std::endl;

    return 0;
}
<commit_msg>Update ex9_14.cpp<commit_after>//! @Alan @pezy
//!
//! Exercise 9.14:
//! Write a program to assign the elements from a list of char* (pointer
//! to C-style character strings) to a vector of string.
//!
//! @Notice C-style character strings should use const char*, otherwise warning.
//!

#include <iostream>
#include <string>
#include <vector>
#include <list>

using namespace std;

int main()
{
    list<const char*> lst{"zhang", "zhi", "zhong"};
    vector<string> svec;
    svec.assign(lst.cbegin(), lst.cend());
    for(const auto &s : svec)
        cout<<s<<" ";
    cout<<endl;
}

<|endoftext|>


<commit_before>//
//  ex9_41.cpp
//  Exercise 9.41
//
//  Created by pezy on 12/4/14.
//
//  @Brief  Write a program that initializes a string from a vector<char>.

#include <iostream>
#include <vector>
#include <string>

using std::vector; using std::cout; using std::endl; using std::string;

int main()
{
    vector<char> vec{ 'p', 'e', 'z', 'y' };
    string str(vec.begin(), vec.end());

    cout << str << endl;

    return 0;
}
<commit_msg>Update ex9_41.cpp<commit_after>//
//  ex9_41.cpp
//  Exercise 9.41
//
//  Created by pezy on 12/4/14.
//
//  @Brief  Write a program that initializes a string from a vector<char>.

#include <iostream>
#include <vector>
#include <string>

using std::vector;
using std::cout;
using std::endl;
using std::string;

int main()
{
    vector<char> v{ 'p', 'e', 'z', 'y' };
    string str(v.cbegin(), v.cend());
    cout << str << endl;

    return 0;
}
<|endoftext|>