text:
/*    Copyright (c) 2010-2019, Delft University of Technology
 *    All rigths reserved
 *
 *    This file is part of the Tudat. Redistribution and use in source and
 *    binary forms, with or without modification, are permitted exclusively
 *    under the terms of the Modified BSD license. You should have received
 *    a copy of the license with this file. If not, please or visit:
 *    http://tudat.tudelft.nl/LICENSE.
 */

#define BOOST_TEST_MAIN

#include <limits>
#include <string>

#include <boost/test/unit_test.hpp>
#include <boost/make_shared.hpp>

#include "Tudat/Basics/testMacros.h"

#include "Tudat/Astrodynamics/GroundStations/pointingAnglesCalculator.h"
#include "Tudat/SimulationSetup/tudatEstimationHeader.h"

namespace tudat
{
namespace unit_tests
{

using namespace tudat::observation_models;
using namespace tudat::spice_interface;
using namespace tudat::ephemerides;
using namespace tudat::simulation_setup;

BOOST_AUTO_TEST_SUITE( test_observation_viability_calculators )

//! Test function to manually compute elevation angle(s) of observation link at given body
std::vector< double > getBodyLinkElevationAngles(
        const LinkEnds linkEnds,
        const ObservableType observableType,
        const std::string referenceBody,
        const std::vector< Eigen::Vector6d > linkEndStates,
        const std::vector< double > linkEndTimes,
        const NamedBodyMap& bodyMap )
{
    std::shared_ptr< ground_stations::PointingAnglesCalculator > currentPointingAnglesCalculator;
    std::vector< double > elevationAngles;
    switch( observableType )
    {
    case one_way_range:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( transmitter ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ), linkEndTimes.at( 0 ) ) );

        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( receiver ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ), linkEndTimes.at( 1 ) ) );
        }
        break;
    }
    case one_way_doppler:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( transmitter ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ), linkEndTimes.at( 0 ) ) );

        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( receiver ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ), linkEndTimes.at( 1 ) ) );
        }
        break;
    }
    case angular_position:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( transmitter ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ), linkEndTimes.at( 0 ) ) );

        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( receiver ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ), linkEndTimes.at( 1 ) ) );
        }
        break;
    }
    case one_way_differenced_range:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( transmitter ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ), linkEndTimes.at( 0 ) ) );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 3 ) - linkEndStates.at( 2 ) ).segment( 0, 3 ), linkEndTimes.at( 2 ) ) );

        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                        linkEnds.at( receiver ).second )->getPointingAnglesCalculator( );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ), linkEndTimes.at( 1 ) ) );
            elevationAngles.push_back( currentPointingAnglesCalculator->calculateElevationAngle(
                                           ( linkEndStates.at( 2 ) - linkEndStates.at( 3 ) ).segment( 0, 3 ), linkEndTimes.at( 3 ) ) );
        }
        break;
    }
    case n_way_range:
    {
        int linkEndIndex = 0;
        for( LinkEnds::const_iterator linkEndIterator = linkEnds.begin( ); linkEndIterator != linkEnds.end( );
             linkEndIterator++ )
        {
            if( linkEndIterator->second.first == referenceBody )
            {
                currentPointingAnglesCalculator = bodyMap.at( referenceBody )->getGroundStation(
                            linkEndIterator->second.second )->getPointingAnglesCalculator( );
                if( linkEndIndex != 0 )
                {
                    elevationAngles.push_back(
                                currentPointingAnglesCalculator->calculateElevationAngle(
                                    ( linkEndStates.at( 2 * ( linkEndIndex - 1 ) ) -
                                      linkEndStates.at( 2 * ( linkEndIndex - 1 ) + 1 ) ).segment( 0, 3 ),
                                    linkEndTimes.at( 2 * ( linkEndIndex - 1 ) + 1 ) ) );
                }

                if( linkEndIndex != static_cast< int >( linkEnds.size( ) ) - 1 )
                {
                    elevationAngles.push_back(
                                currentPointingAnglesCalculator->calculateElevationAngle(
                                    ( linkEndStates.at( 2 * linkEndIndex + 1) -
                                      linkEndStates.at( 2 * linkEndIndex ) ).segment( 0, 3 ),
                                    linkEndTimes.at( 2 * linkEndIndex ) ) );
                }

            }
            linkEndIndex++;
        }
        break;
    }
    default:
        throw std::runtime_error( "Error when testing elevation angle viability, observable not recognized" );

    }

    return elevationAngles;
}

//! Test function to manually compute body avoidance angle(s) of observation link at given body
std::vector< double > getBodyCosineAvoidanceAngles(
        const LinkEnds linkEnds,
        const ObservableType observableType,
        const std::string referenceBody,
        const std::string bodyToAvoid,
        const std::vector< Eigen::Vector6d > linkEndStates,
        const std::vector< double > linkEndTimes,
        const NamedBodyMap& bodyMap )
{
    std::vector< double > cosineAvoidanceAngles;
    switch( observableType )
    {
    case one_way_range:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 0 ).segment( 0, 3 ) ) ) );
        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 1 ).segment( 0, 3 ) ) ) );
        }
        break;
    }
    case one_way_doppler:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 0 ).segment( 0, 3 ) ) ) );
        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 1 ).segment( 0, 3 ) ) ) );
        }
        break;
    }
    case angular_position:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 0 ).segment( 0, 3 ) ) ) );
        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 1 ).segment( 0, 3 ) ) ) );
        }
        break;
    }
    case one_way_differenced_range:
    {
        if( linkEnds.at( transmitter ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 1 ) - linkEndStates.at( 0 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 0 ).segment( 0, 3 ) ) ) );
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 3 ) - linkEndStates.at( 2 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 3 ) + linkEndTimes.at( 2 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 2 ).segment( 0, 3 ) ) ) );
        }
        else if( linkEnds.at( receiver ).first == referenceBody )
        {
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 0 ) - linkEndStates.at( 1 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 1 ) + linkEndTimes.at( 0 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 1 ).segment( 0, 3 ) ) ) );
            cosineAvoidanceAngles.push_back(
                        linear_algebra::computeCosineOfAngleBetweenVectors(
                            ( ( linkEndStates.at( 2 ) - linkEndStates.at( 3 ) ).segment( 0, 3 ) ), (
                                bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                    ( linkEndTimes.at( 3 ) + linkEndTimes.at( 2 ) ) / 2.0 ).segment( 0, 3 ) -
                                linkEndStates.at( 3 ).segment( 0, 3 ) ) ) );
        }
        break;
    }
    case n_way_range:
    {
        int linkEndIndex = 0;
        for( LinkEnds::const_iterator linkEndIterator = linkEnds.begin( ); linkEndIterator != linkEnds.end( );
             linkEndIterator++ )
        {
            if( linkEndIterator->second.first == referenceBody )
            {
                if( linkEndIndex != 0 )
                {
                    cosineAvoidanceAngles.push_back(
                                linear_algebra::computeCosineOfAngleBetweenVectors(
                                    ( ( linkEndStates.at( 2 * ( linkEndIndex - 1 ) ) -
                                        linkEndStates.at( 2 * ( linkEndIndex - 1 ) + 1 ) ).segment( 0, 3 ) ), (
                                        bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                            ( linkEndTimes.at( 2 * ( linkEndIndex - 1 ) + 1  ) +
                                              linkEndTimes.at( 2 * ( linkEndIndex - 1 ) ) ) / 2.0 ).segment( 0, 3 ) -
                                        linkEndStates.at( 2 * ( linkEndIndex - 1 ) + 1 ).segment( 0, 3 ) ) ) );
                }

                if( linkEndIndex != static_cast< int >( linkEnds.size( ) ) - 1 )
                {
                    cosineAvoidanceAngles.push_back(
                                linear_algebra::computeCosineOfAngleBetweenVectors(
                                    ( linkEndStates.at( 2 * linkEndIndex + 1 ) -
                                      linkEndStates.at( 2 * linkEndIndex ) ).segment( 0, 3 ), (
                                        bodyMap.at( bodyToAvoid )->getStateInBaseFrameFromEphemeris< double, double >(
                                            ( linkEndTimes.at( 2 * linkEndIndex + 1  ) +
                                              linkEndTimes.at( 2 * linkEndIndex  ) ) / 2.0 ).segment( 0, 3 ) -
                                        linkEndStates.at( 2 * linkEndIndex ).segment( 0, 3 ) ) ) );
                }

            }
            linkEndIndex++;
        }
        break;
    }
    default:
        throw std::runtime_error( "Error when testing avoidance angle viability, observable not recognized" );

    }

    return cosineAvoidanceAngles;
}

//! Test function to manually compute body distance between body center of mass and observation link vector
std::vector< double > getDistanceBetweenLineOfSightVectorAndPoint(
        const std::string bodyToAnalyze,
        const std::vector< Eigen::Vector6d > linkEndStates,
        const std::vector< double > linkEndTimes,
        const NamedBodyMap& bodyMap )
{
    std::vector< double > pointDistances;
    for( unsigned int i = 0; i < linkEndStates.size( ); i += 2 )
    {
        Eigen::Vector3d linkEnd1Position = linkEndStates.at( i ).segment( 0, 3 );
        Eigen::Vector3d linkEnd2Position = linkEndStates.at( i + 1 ).segment( 0, 3 );

        Eigen::Vector3d pointPosition = bodyMap.at( bodyToAnalyze )->getStateInBaseFrameFromEphemeris< double, double >(
                    ( linkEndTimes.at( i ) + linkEndTimes.at( i ) ) / 2.0 ).segment( 0, 3 );

        pointDistances.push_back( ( ( linkEnd2Position - pointPosition ).cross( linkEnd1Position - pointPosition ) ).norm( ) /
                                  ( linkEnd2Position - linkEnd1Position ).norm( ) );

    }
    return pointDistances;
}

//! Test if observation viability calculators correctly constrain observations
/*!
 *  Test if observation viability calculators correctly constrain observations. Test is performed for a list of observables,
 *  and a list of link ends per observable. The elevation angle, occultation and avoidance angle conditions are all checked.
 */
BOOST_AUTO_TEST_CASE( testObservationViabilityCalculators )
{
    //Load spice kernels.
    spice_interface::loadStandardSpiceKernels( );

    // Define environment settings
    std::vector< std::string > bodyNames;
    bodyNames.push_back( "Earth" );
    bodyNames.push_back( "Mars" );
    bodyNames.push_back( "Sun" );
    bodyNames.push_back( "Moon" );

    std::map< std::string, std::shared_ptr< BodySettings > > bodySettings =
            getDefaultBodySettings( bodyNames );

    // Set simplified rotation models for Earth/Mars (spice rotation retrieval is slow)
    bodySettings[ "Earth" ]->rotationModelSettings = std::make_shared< SimpleRotationModelSettings >(
                "ECLIPJ2000", "IAU_Earth",
                spice_interface::computeRotationQuaternionBetweenFrames(
                    "ECLIPJ2000", "IAU_Earth", 0.0 ),
                0.0, 2.0 * mathematical_constants::PI /
                ( physical_constants::JULIAN_DAY ) );
    bodySettings[ "Mars" ]->rotationModelSettings = std::make_shared< SimpleRotationModelSettings >(
                "ECLIPJ2000", "IAU_Mars",
                spice_interface::computeRotationQuaternionBetweenFrames(
                    "ECLIPJ2000", "IAU_Mars", 0.0 ),
                0.0, 2.0 * mathematical_constants::PI /
                ( physical_constants::JULIAN_DAY + 40.0 * 60.0 ) );

    // Set unrealistically large radius of Moon to make iss occultation mode significant
    double moonRadius = 1.0E9;
    bodySettings[ "Moon" ]->shapeModelSettings = std::make_shared< SphericalBodyShapeSettings >( moonRadius );

    // Create list of body objects
    NamedBodyMap bodyMap = createBodies( bodySettings );
    setGlobalFrameBodyEphemerides( bodyMap, "SSB", "ECLIPJ2000" );

    // Create ground stations
    std::pair< std::string, std::string > earthStation1 = std::pair< std::string, std::string >( "Earth", "EarthStation1" );
    std::pair< std::string, std::string > earthStation2 = std::pair< std::string, std::string >( "Earth", "EarthStation2" );
    std::pair< std::string, std::string > mslStation1 = std::pair< std::string, std::string >( "Mars", "MarsStation1" );
    std::pair< std::string, std::string > mslStation2 = std::pair< std::string, std::string >( "Mars", "MarsStation2" );
    createGroundStation( bodyMap.at( "Mars" ), "MarsStation1", ( Eigen::Vector3d( ) << 100.0, 0.2, 2.1 ).finished( ),
                         coordinate_conversions::geodetic_position );
    createGroundStation( bodyMap.at( "Mars" ), "MarsStation2", ( Eigen::Vector3d( ) << -2000.0, -0.4, 0.1 ).finished( ),
                         coordinate_conversions::geodetic_position );
    createGroundStation( bodyMap.at( "Earth" ), "EarthStation1", ( Eigen::Vector3d( ) << 800.0, 0.12, 5.3 ).finished( ),
                         coordinate_conversions::geodetic_position );
    createGroundStation( bodyMap.at( "Earth" ), "EarthStation2", ( Eigen::Vector3d( ) << 100.0, 0.15, 0.0 ).finished( ),
                         coordinate_conversions::geodetic_position );

    // Define one-way range/one-way Doppler/angular position/one-way differenced range link ends
    LinkEnds oneWayLinkEnds1;
    oneWayLinkEnds1[ transmitter ] = std::make_pair( "Mars", "MarsStation1" );
    oneWayLinkEnds1[ receiver ] = std::make_pair( "Earth", "EarthStation1" );

    LinkEnds oneWayLinkEnds2;
    oneWayLinkEnds2[ transmitter ] = std::make_pair( "Earth", "EarthStation2" );
    oneWayLinkEnds2[ receiver ] = std::make_pair( "Mars", "MarsStation2" );

    LinkEnds oneWayLinkEnds3;
    oneWayLinkEnds3[ transmitter ] = std::make_pair( "Mars", "MarsStation1" );
    oneWayLinkEnds3[ receiver ] = std::make_pair( "Earth", "EarthStation2" );

    std::vector< LinkEnds > oneWayRangeLinkEnds;
    oneWayRangeLinkEnds.push_back( oneWayLinkEnds1 );
    oneWayRangeLinkEnds.push_back( oneWayLinkEnds2 );
    oneWayRangeLinkEnds.push_back( oneWayLinkEnds3 );

    // Define two-way range link ends
    LinkEnds twoWayLinkEnds1;
    twoWayLinkEnds1[ transmitter ] = std::make_pair( "Mars", "MarsStation1" );
    twoWayLinkEnds1[ reflector1 ] = std::make_pair( "Earth", "EarthStation1" );
    twoWayLinkEnds1[ receiver ] = std::make_pair( "Mars", "MarsStation1" );

    LinkEnds twoWayLinkEnds2;
    twoWayLinkEnds2[ transmitter ] = std::make_pair( "Earth", "EarthStation2" );
    twoWayLinkEnds2[ reflector1 ] = std::make_pair( "Mars", "MarsStation2" );
    twoWayLinkEnds2[ receiver ] = std::make_pair( "Earth", "EarthStation1" );

    LinkEnds twoWayLinkEnds3;
    twoWayLinkEnds3[ transmitter ] = std::make_pair( "Mars", "MarsStation2" );
    twoWayLinkEnds3[ reflector1 ] = std::make_pair( "Earth", "EarthStation2" );
    twoWayLinkEnds3[ receiver ] = std::make_pair( "Mars", "MarsStation1" );
    std::vector< LinkEnds > twoWayRangeLinkEnds;
    twoWayRangeLinkEnds.push_back( twoWayLinkEnds1 );
    twoWayRangeLinkEnds.push_back( twoWayLinkEnds2 );
    twoWayRangeLinkEnds.push_back( twoWayLinkEnds3 );

    // Create list of link ends per obsevables
    std::map< ObservableType, std::vector< LinkEnds > > testLinkEndsList;
    testLinkEndsList[ one_way_range ] = oneWayRangeLinkEnds;
    testLinkEndsList[ one_way_differenced_range ] = oneWayRangeLinkEnds;
    testLinkEndsList[ angular_position ] = oneWayRangeLinkEnds;
    testLinkEndsList[ n_way_range ] = twoWayRangeLinkEnds;

    // Define list of observation times that are to be checked: one observation every 2.5 days, over a period of 10 years.
    std::vector< double > unconstrainedObservationTimes;
    LinkEndType referenceLinkEnd = transmitter;
    double initialTime = 0.0, finalTime = 10.0 * physical_constants::JULIAN_YEAR, timeStep = physical_constants::JULIAN_DAY * 2.5;
    double currentTime = initialTime;
    while( currentTime <= finalTime )
    {
        unconstrainedObservationTimes.push_back( currentTime );
        currentTime += timeStep;
    }
    int unconstrainedNumberOfObservations = unconstrainedObservationTimes.size( );

    // Create observation model and observation time settings for all observables
    std::map< ObservableType, std::map< LinkEnds, std::shared_ptr< ObservationSimulationTimeSettings< double > > > >
            observationTimeSettings;
    typedef std::map< ObservableType, std::map< LinkEnds, std::shared_ptr< ObservationSettings > > > SortedObservationSettingsMap;
    SortedObservationSettingsMap observationSettingsMap;
    for( std::map< ObservableType, std::vector< LinkEnds > >::const_iterator observableIterator = testLinkEndsList.begin( );
         observableIterator != testLinkEndsList.end( ); observableIterator++ )
    {
        for( unsigned int i = 0; i < observableIterator->second.size( ); i++ )
        {
            if( observableIterator->first == one_way_differenced_range )
            {
                observationSettingsMap[ observableIterator->first ][ observableIterator->second.at( i ) ] =
                        std::make_shared< OneWayDifferencedRangeRateObservationSettings >(
                            [ ]( const double ){ return 60.0; }, std::shared_ptr< LightTimeCorrectionSettings > ( ) );
            }
            else if( observableIterator->first == n_way_range )
            {
                observationSettingsMap[ observableIterator->first ][ observableIterator->second.at( i ) ] =
                        std::make_shared< NWayRangeObservationSettings >(
                            std::shared_ptr< LightTimeCorrectionSettings >( ), observableIterator->second.at( i ).size( ) );
            }
            else
            {
                observationSettingsMap[ observableIterator->first ][ observableIterator->second.at( i ) ] =
                        std::make_shared< ObservationSettings >(
                            observableIterator->first, std::shared_ptr< LightTimeCorrectionSettings >( ) );

            }
            observationTimeSettings[ observableIterator->first ][ observableIterator->second.at( i ) ] =
                    std::make_shared< TabulatedObservationSimulationTimeSettings< double > >(
                        referenceLinkEnd, unconstrainedObservationTimes );
        }
    }

   // Define minimum elevation angles for Earth/Mars stations
    double earthMinimumElevationAngle = 4.0 * mathematical_constants::PI / 180.0;
    double marsMinimumElevationAngle = 10.0 * mathematical_constants::PI / 180.0;

    // Define minimum Sun avoidance angles for Earth/Mars stations
    double earthSunAvoidanceAngle = 30.0 * mathematical_constants::PI / 180.0;
    double marsSunAvoidanceAngle = 21.0 * mathematical_constants::PI / 180.0;

    // Create observation viability settings
    std::vector< std::shared_ptr< ObservationViabilitySettings > > observationViabilitySettings;
    observationViabilitySettings.push_back( std::make_shared< ObservationViabilitySettings >(
                                                minimum_elevation_angle, std::make_pair( "Earth", "" ), "",
                                                earthMinimumElevationAngle ) );
    observationViabilitySettings.push_back( std::make_shared< ObservationViabilitySettings >(
                                                minimum_elevation_angle, std::make_pair( "Mars", "" ), "",
                                                marsMinimumElevationAngle ) );
    observationViabilitySettings.push_back( std::make_shared< ObservationViabilitySettings >(
                                                body_avoidance_angle, std::make_pair( "Earth", "" ), "Sun",
                                                earthSunAvoidanceAngle ) );
    observationViabilitySettings.push_back( std::make_shared< ObservationViabilitySettings >(
                                                body_avoidance_angle, std::make_pair( "Mars", "" ), "Sun",
                                                marsSunAvoidanceAngle ) );
    observationViabilitySettings.push_back( std::make_shared< ObservationViabilitySettings >(
                                                body_occultation, std::make_pair( "Earth", "" ), "Moon" ) );

    // Create observation viability calculators
    PerObservableObservationViabilityCalculatorList viabilityCalculators = createObservationViabilityCalculators(
                bodyMap, testLinkEndsList, observationViabilitySettings );

    // Create osbervation simulatos
    std::map< ObservableType,  std::shared_ptr< ObservationSimulatorBase< double, double > > > observationSimulators =
            createObservationSimulators( observationSettingsMap , bodyMap );

    // Simulate observations without constraints directly from simulateObservations function
    std::map< ObservableType, std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > > >
            unconstrainedSimulatedObservables = removeLinkIdFromSimulatedObservations(
                simulateObservations( observationTimeSettings,observationSimulators ) );

    // Simulate observations with viability constraints directly from simulateObservations function
    std::map< ObservableType, std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > > >
            constrainedSimulatedObservables = removeLinkIdFromSimulatedObservations(
                simulateObservations( observationTimeSettings, observationSimulators, viabilityCalculators ) );

    // Simulate observations without/with viability constraints directly from ObservationSimulator objects
    std::map< ObservableType, std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > > >
            unconstrainedSimulatedObservablesFromObjects;
    std::map< ObservableType, std::map< LinkEnds,  std::pair< Eigen::VectorXd, std::vector< double > > > >
            constrainedSimulatedObservablesFromObjects;
    for( std::map< ObservableType,  std::shared_ptr< ObservationSimulatorBase< double, double > > >::iterator
         simulatorIterator = observationSimulators.begin( ); simulatorIterator != observationSimulators.end( );
         simulatorIterator++ )
    {
        // Simulate unconstrained observations for current observable ObservationSimulator object
        for( unsigned int i = 0; i < testLinkEndsList.at( simulatorIterator->first ).size( ); i++ )
        {
            unconstrainedSimulatedObservablesFromObjects[ simulatorIterator->first ][
                    testLinkEndsList.at( simulatorIterator->first ).at ( i ) ] = simulatorIterator->second->simulateObservations(
                        unconstrainedObservationTimes,  testLinkEndsList.at( simulatorIterator->first ).at ( i ),
                        referenceLinkEnd, false );
        }

        // Simulate viability-constrained observations for current observable ObservationSimulator object
        if( viabilityCalculators.count( simulatorIterator->first ) > 0 )
        {
            simulatorIterator->second->setViabilityCalculators( viabilityCalculators.at( simulatorIterator->first ) );
        }
        for( unsigned int i = 0; i < testLinkEndsList.at( simulatorIterator->first ).size( ); i++ )
        {
            constrainedSimulatedObservablesFromObjects[ simulatorIterator->first ][
                    testLinkEndsList.at( simulatorIterator->first ).at ( i ) ] = simulatorIterator->second->simulateObservations(
                        unconstrainedObservationTimes,  testLinkEndsList.at( simulatorIterator->first ).at ( i ),
                        referenceLinkEnd, true );
        }
    }

    int numberOfObsevables = testLinkEndsList.size( );

    // Check consistency of simulated observations from ObservationSimulator objects/simulateObservations function
    BOOST_CHECK_EQUAL( numberOfObsevables, unconstrainedSimulatedObservablesFromObjects.size( ) );
    BOOST_CHECK_EQUAL( numberOfObsevables, constrainedSimulatedObservablesFromObjects.size( ) );

    BOOST_CHECK_EQUAL( numberOfObsevables, constrainedSimulatedObservables.size( ) );
    BOOST_CHECK_EQUAL( numberOfObsevables, constrainedSimulatedObservablesFromObjects.size( ) );

    // Create iterators over all simulated observations
    std::map< ObservableType, std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > > >::iterator
            unconstrainedIterator = unconstrainedSimulatedObservables.begin( );
    std::map< ObservableType, std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > > >::iterator
            unconstrainedIteratorFromObjects = unconstrainedSimulatedObservablesFromObjects.begin( );

    std::map< ObservableType, std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > > >::iterator
            constrainedIterator = constrainedSimulatedObservables.begin( );
    std::map< ObservableType, std::map< LinkEnds,  std::pair< Eigen::VectorXd, std::vector< double > > > >::iterator
            constrainedIteratorFromObjects = constrainedSimulatedObservablesFromObjects.begin( );

    std::vector< double > linkEndTimes;
    std::vector< Eigen::Vector6d > linkEndStates;

    // Iterate over all observations and check viability constraints
    for( int i = 0; i < numberOfObsevables; i++ )
    {
        int numberOfLinkEnds = testLinkEndsList.at( unconstrainedIterator->first ).size( );
        int currentObservableSize = getObservableSize( unconstrainedIterator->first );

        // Check consistency of simulated observations from ObservationSimulator objects/simulateObservations function
        BOOST_CHECK_EQUAL( numberOfLinkEnds, unconstrainedIterator->second.size( ) );
        BOOST_CHECK_EQUAL( numberOfLinkEnds, unconstrainedIteratorFromObjects->second.size( ) );

        BOOST_CHECK_EQUAL( numberOfLinkEnds, constrainedIterator->second.size( ) );
        BOOST_CHECK_EQUAL( numberOfLinkEnds, constrainedIteratorFromObjects->second.size( ) );

        // Create iterators over all simulated observations of current observable
        std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > >::iterator unconstrainedLinkIterator =
                unconstrainedIterator->second.begin( );
        std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > >::iterator unconstrainedLinkIteratorFromObjects =
                unconstrainedIteratorFromObjects->second.begin( );
        std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > >::iterator constrainedLinkIterator =
                constrainedIterator->second.begin( );
        std::map< LinkEnds, std::pair< Eigen::VectorXd, std::vector< double > > >::iterator constrainedLinkIteratorFromObjects =
                constrainedIteratorFromObjects->second.begin( );

        ObservableType currentObservable = unconstrainedIterator->first;

        std::shared_ptr< ObservationSimulatorBase< double, double > > currentObservationSimulator =
                observationSimulators.at( currentObservable );

        // Iterate over all link ends of current observables.
        for( int j = 0; j < numberOfLinkEnds; j++ )
        {
            LinkEnds currentLinkEnds = unconstrainedLinkIterator->first;

            std::vector< std::shared_ptr< ObservationViabilityCalculator > > currentViabilityCalculators =
                    viabilityCalculators.at( currentObservable ).at( currentLinkEnds );

            // Check consistency of simulated observations from ObservationSimulator objects/simulateObservations function
            BOOST_CHECK_EQUAL( unconstrainedNumberOfObservations, unconstrainedLinkIterator->second.second.size( ) );
            BOOST_CHECK_EQUAL( unconstrainedNumberOfObservations, unconstrainedLinkIteratorFromObjects->second.second.size( ) );

            BOOST_CHECK_EQUAL( unconstrainedNumberOfObservations * currentObservableSize, unconstrainedLinkIterator->second.first.rows( ) );
            BOOST_CHECK_EQUAL( unconstrainedNumberOfObservations * currentObservableSize, unconstrainedLinkIteratorFromObjects->second.first.rows( ) );

            BOOST_CHECK_EQUAL( constrainedLinkIteratorFromObjects->second.second.size( ), constrainedLinkIterator->second.second.size( ) );
            BOOST_CHECK_EQUAL( constrainedLinkIteratorFromObjects->second.first.rows( ), constrainedLinkIterator->second.first.rows( ) );

            BOOST_CHECK_EQUAL( constrainedLinkIteratorFromObjects->second.first.rows( ),
                               constrainedLinkIteratorFromObjects->second.second.size( ) * currentObservableSize );

            int unconstrainedIndex = 0, constrainedIndex = 0;
            bool currentObservationWasViable, currentObservationIsViable, isSingleViabilityConditionMet;
            Eigen::VectorXd currentObservation;

            // Retrieve observations for current link ends/observable type
            std::pair< Eigen::VectorXd, std::vector< double > > unconstrainedSingleLinkObservations
                    = unconstrainedLinkIterator->second;
            std::pair< Eigen::VectorXd, std::vector< double > > constrainedSingleLinkObservations
                    = constrainedLinkIterator->second;

            // Iterate over all unconstrained observations for current observable/link ends
            while( unconstrainedIndex < unconstrainedNumberOfObservations )
            {
                // Check if current observation was rejected by viability calculators
                if( constrainedIndex >= static_cast< int >( constrainedSingleLinkObservations.second.size( ) ) )
                {
                    currentObservationWasViable = false;
                }
                else if( unconstrainedSingleLinkObservations.second.at( unconstrainedIndex ) ==
                         constrainedSingleLinkObservations.second.at( constrainedIndex ) )
                {
                    currentObservationWasViable = true;
                }
                else
                {
                    currentObservationWasViable = false;
                }

                // Re-simulate current observation
                currentObservation = currentObservationSimulator->simulateObservation(
                            unconstrainedObservationTimes.at( unconstrainedIndex ), currentLinkEnds, referenceLinkEnd,
                            linkEndTimes, linkEndStates );

                // Re-compute viability according to viability calculator objects.
                currentObservationIsViable = true;
                for( unsigned int k = 0; k < currentViabilityCalculators.size( ); k++ )
                {
                    isSingleViabilityConditionMet = currentViabilityCalculators.at( k )->isObservationViable(
                                linkEndStates, linkEndTimes );
                    if( !isSingleViabilityConditionMet )
                    {
                        currentObservationIsViable = false;
                    }
                }

                // Manually recompute mars elevation angle condition
                std::vector< double > marsElevationAngles = getBodyLinkElevationAngles(
                            currentLinkEnds, currentObservable, "Mars", linkEndStates, linkEndTimes, bodyMap );
                bool computedViability = true;
                for( unsigned int l = 0; l < marsElevationAngles.size( ); l++ )
                {
                    if( marsElevationAngles.at( l ) < marsMinimumElevationAngle )
                    {
                        computedViability =  false;
                    }
                }

                // Manually recompute earth elevation angle condition
                std::vector< double > earthElevationAngles = getBodyLinkElevationAngles(
                            currentLinkEnds, currentObservable, "Earth", linkEndStates, linkEndTimes, bodyMap );
                for( unsigned int l = 0; l < earthElevationAngles.size( ); l++ )
                {
                    if( earthElevationAngles.at( l ) < earthMinimumElevationAngle )
                    {
                        computedViability =  false;
                    }
                }

                // Manually recompute earth-Sun avoidance angle condition
                std::vector< double > earthSunCosineAvoidanceAngles = getBodyCosineAvoidanceAngles(
                            currentLinkEnds, currentObservable, "Earth", "Sun", linkEndStates, linkEndTimes, bodyMap );
                for( unsigned int l = 0; l < earthSunCosineAvoidanceAngles.size( ); l++ )
                {
                    if( earthSunCosineAvoidanceAngles.at( l ) > std::cos( earthSunAvoidanceAngle ) )
                    {
                        computedViability =  false;
                    }
                }

                // Manually recompute mars-Sun avoidance angle condition
                std::vector< double > marsSunCosineAvoidanceAngles = getBodyCosineAvoidanceAngles(
                            currentLinkEnds, currentObservable, "Mars", "Sun", linkEndStates, linkEndTimes, bodyMap );
                for( unsigned int l = 0; l < marsSunCosineAvoidanceAngles.size( ); l++ )
                {
                    if( marsSunCosineAvoidanceAngles.at( l ) > std::cos( marsSunAvoidanceAngle ) )
                    {
                        computedViability =  false;
                    }
                }

                // Manually recompute occultataion consition
                std::vector< double > moonLineOfSightDistances = getDistanceBetweenLineOfSightVectorAndPoint(
                            "Moon", linkEndStates, linkEndTimes, bodyMap );
                for( unsigned int l = 0; l < moonLineOfSightDistances.size( ); l++ )
                {
                    if( moonLineOfSightDistances.at( l ) < moonRadius )
                    {
                        computedViability =  false;
                    }
                }

                // Check manual/automatic viability check
                BOOST_CHECK_EQUAL( currentObservationIsViable, currentObservationWasViable );
                BOOST_CHECK_EQUAL( computedViability, currentObservationWasViable );

                if( currentObservationWasViable )
                {
                    constrainedIndex++;
                }
                unconstrainedIndex++;
            }
            BOOST_CHECK_EQUAL( constrainedIndex, constrainedLinkIteratorFromObjects->second.second.size( ) );

            unconstrainedLinkIterator++;
            unconstrainedLinkIteratorFromObjects++;
            constrainedLinkIterator++;
            constrainedLinkIteratorFromObjects++;
        }

        unconstrainedIterator++;
        unconstrainedIteratorFromObjects++;
        constrainedIterator++;
        constrainedIteratorFromObjects++;
    }
}

BOOST_AUTO_TEST_SUITE_END( )

}

}

max_stars_repo_name: sebranchett/tudat

max_issues_repo_name: sebranchett/tudat

max_forks_repo_name: sebranchett/tudat


text:
/* CirKit: A circuit toolkit
 * Copyright (C) 2009-2015  University of Bremen
 * Copyright (C) 2015-2017  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include "is_identity.hpp"

#include <boost/range/combine.hpp>
#include <boost/range/numeric.hpp>

#include <reversible/rcbdd.hpp>

namespace cirkit
{

bool is_identity( const circuit& circ )
{
  rcbdd mgr;
  mgr.initialize_manager();
  mgr.create_variables( circ.lines() );

  BDD f = mgr.create_from_circuit( circ );

  BDD identity = boost::accumulate( boost::combine( mgr.xs(), mgr.ys() ),
                                    mgr.manager().bddOne(),
                                    []( BDD current, const boost::tuple<BDD, BDD>& t ) {
                                      return current & ( boost::get<0>( t ).Xnor( boost::get<1>( t ) ) );
                                    } );

  return f == identity;
}

}

// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End:

ext: cpp

max_stars_repo_name: eletesta/cirkit

max_issues_repo_name: eletesta/cirkit

max_forks_repo_name: eletesta/cirkit


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

#pragma once

#include <tf2/LinearMath/Quaternion.h>
#include <tf2/LinearMath/Vector3.h>

#include <Eigen/Dense>
// #include <tf2_geometry_msgs/tf2_geometry_msgs.hpp>
#include <tf2_kdl/tf2_kdl.hpp>
#include <vector>

namespace bio_ik {

typedef tf2::Quaternion Quaternion;
typedef tf2::Vector3 Vector3;

struct Frame {
  Vector3 pos;
  std::array<double, 4 - (sizeof(Vector3) / sizeof(double))> __padding;
  Quaternion rot;
  inline Frame() {}
  inline Frame(const tf2::Vector3& _pos, const tf2::Quaternion& _rot)
      : pos(_pos), rot(_rot) {}
  explicit inline Frame(const KDL::Frame& kdl) {
    pos = tf2::Vector3(kdl.p.x(), kdl.p.y(), kdl.p.z());
    double qx, qy, qz, qw;
    kdl.M.GetQuaternion(qx, qy, qz, qw);
    rot = tf2::Quaternion(qx, qy, qz, qw);
  }
  explicit inline Frame(const geometry_msgs::msg::Pose& msg) {
    tf2::fromMsg(msg.orientation, rot);
    pos = tf2::Vector3(msg.position.x, msg.position.y, msg.position.z);
  }
  explicit inline Frame(const Eigen::Isometry3d& f) {
    pos = tf2::Vector3(f.translation().x(), f.translation().y(),
                       f.translation().z());
    Eigen::Quaterniond q(f.rotation());
    rot = tf2::Quaternion(q.x(), q.y(), q.z(), q.w());
  }

  inline const Vector3& getPosition() const { return pos; }
  inline const Quaternion& getOrientation() const { return rot; }
  inline void setPosition(const Vector3& p) { pos = p; }
  inline void setOrientation(const Quaternion& q) { rot = q; }

 private:
  template <size_t i>
  struct IdentityFrameTemplate {
    static const Frame identity_frame;
  };

 public:
  static inline const Frame& identity() {
    return IdentityFrameTemplate<0>::identity_frame;
  }
};

inline void frameToKDL(const Frame& frame, KDL::Frame& kdl_frame) {
  kdl_frame.p.x(frame.pos.x());
  kdl_frame.p.y(frame.pos.y());
  kdl_frame.p.z(frame.pos.z());
  kdl_frame.M = KDL::Rotation::Quaternion(frame.rot.x(), frame.rot.y(),
                                          frame.rot.z(), frame.rot.w());
}

template <size_t i>
const Frame Frame::IdentityFrameTemplate<i>::identity_frame(Vector3(0, 0, 0),
                                                            Quaternion(0, 0, 0,
                                                                       1));

// TODO(tylerjw): use this?
// static std::ostream& operator<<(std::ostream& os, const Frame& f) {
//   return os << "(" << f.pos.x() << "," << f.pos.y() << "," << f.pos.z() <<
//   ";"
//             << f.rot.x() << "," << f.rot.y() << "," << f.rot.z() << ","
//             << f.rot.w() << ")";
// }

__attribute__((always_inline)) inline void quat_mul_vec(
    const tf2::Quaternion& q, const tf2::Vector3& v, tf2::Vector3& r) {
  double v_x = v.x();
  double v_y = v.y();
  double v_z = v.z();

  // if(__builtin_expect(v_x == 0 && v_y == 0 && v_z == 0, 0)) { r =
  // tf2::Vector3(0, 0, 0); return; } if(v_x == 0 && v_y == 0 && v_z == 0) { r =
  // tf2::Vector3(0, 0, 0); return; }

  double q_x = q.x();
  double q_y = q.y();
  double q_z = q.z();
  double q_w = q.w();

  if ((v_x == 0 && v_y == 0 && v_z == 0) ||
      (q_x == 0 && q_y == 0 && q_z == 0 && q_w == 1)) {
    r = v;
    return;
  }
  // if((v_x + v_y + v_z == 0 && v_x == 0 && v_y == 0) || (q_x + q_y + q_z == 0
  // && q_x == 0 && q_y == 0 && q_w == 1)) { r = v; return; } if(q_x == 0 && q_y
  // == 0 && q_z == 0 && q_w == 1) { r = v; return; }

  double t_x = q_y * v_z - q_z * v_y;
  double t_y = q_z * v_x - q_x * v_z;
  double t_z = q_x * v_y - q_y * v_x;

  double r_x = q_w * t_x + q_y * t_z - q_z * t_y;
  double r_y = q_w * t_y + q_z * t_x - q_x * t_z;
  double r_z = q_w * t_z + q_x * t_y - q_y * t_x;

  r_x += r_x;
  r_y += r_y;
  r_z += r_z;

  r_x += v_x;
  r_y += v_y;
  r_z += v_z;

  r.setX(r_x);
  r.setY(r_y);
  r.setZ(r_z);
}

__attribute__((always_inline)) inline void quat_mul_quat(
    const tf2::Quaternion& p, const tf2::Quaternion& q, tf2::Quaternion& r) {
  double p_x = p.x();
  double p_y = p.y();
  double p_z = p.z();
  double p_w = p.w();

  double q_x = q.x();
  double q_y = q.y();
  double q_z = q.z();
  double q_w = q.w();

  double r_x = (p_w * q_x + p_x * q_w) + (p_y * q_z - p_z * q_y);
  double r_y = (p_w * q_y - p_x * q_z) + (p_y * q_w + p_z * q_x);
  double r_z = (p_w * q_z + p_x * q_y) - (p_y * q_x - p_z * q_w);
  double r_w = (p_w * q_w - p_x * q_x) - (p_y * q_y + p_z * q_z);

  r.setX(r_x);
  r.setY(r_y);
  r.setZ(r_z);
  r.setW(r_w);
}

__attribute__((always_inline)) inline void concat(const Frame& a,
                                                  const Frame& b, Frame& r) {
  tf2::Vector3 d;
  quat_mul_vec(a.rot, b.pos, d);
  r.pos = a.pos + d;
  quat_mul_quat(a.rot, b.rot, r.rot);
}

__attribute__((always_inline)) inline void concat(const Frame& a,
                                                  const Frame& b,
                                                  const Frame& c, Frame& r) {
  Frame tmp;
  concat(a, b, tmp);
  concat(tmp, c, r);
}

__attribute__((always_inline)) inline void quat_inv(const tf2::Quaternion& q,
                                                    tf2::Quaternion& r) {
  r.setX(-q.x());
  r.setY(-q.y());
  r.setZ(-q.z());
  r.setW(q.w());
}

__attribute__((always_inline)) inline void invert(const Frame& a, Frame& r) {
  Frame tmp;
  quat_inv(a.rot, r.rot);
  quat_mul_vec(r.rot, -a.pos, r.pos);
}

__attribute__((always_inline)) inline void change(const Frame& a,
                                                  const Frame& b,
                                                  const Frame& c, Frame& r) {
  Frame tmp;
  invert(b, tmp);
  concat(a, tmp, c, r);
}

__attribute__((always_inline)) inline Frame inverse(const Frame& f) {
  Frame r;
  invert(f, r);
  return r;
}

__attribute__((always_inline)) inline Frame operator*(const Frame& a,
                                                      const Frame& b) {
  Frame r;
  concat(a, b, r);
  return r;
}

__attribute__((always_inline)) inline Frame& operator*=(Frame& a,
                                                        const Frame& b) {
  a = a * b;
  return a;
}

__attribute__((always_inline)) inline void normalizeFast(Quaternion& q) {
  double f = (3.0 - q.length2()) * 0.5;
  q.setX(q.x() * f);
  q.setY(q.y() * f);
  q.setZ(q.z() * f);
  q.setW(q.w() * f);
}

__attribute__((always_inline)) inline KDL::Twist frameTwist(const Frame& a,
                                                            const Frame& b) {
  auto frame = inverse(a) * b;
  KDL::Twist t;
  t.vel.x(frame.pos.x());
  t.vel.y(frame.pos.y());
  t.vel.z(frame.pos.z());

  double ra = frame.rot.getAngle();
  // double ra = frame.rot.getAngleShortestPath();
  if (ra > +M_PI) ra -= 2 * M_PI;
  // if(ra < -M_PI) ra += 2 * M_PI;

  auto r = frame.rot.getAxis() * ra;
  t.rot.x(r.x());
  t.rot.y(r.y());
  t.rot.z(r.z());

  return t;
}
}  // namespace bio_ik

ext: hpp


text:
/***********************************************************************
Moses - factored phrase-based language decoder
Copyright (C) 2014- University of Edinburgh

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
***********************************************************************/
#include <iostream>
#include <set>

#include <boost/lexical_cast.hpp>

#include "util/double-conversion/double-conversion.h"
#include "util/string_piece.hh"
#include "util/tokenize_piece.hh"

#include "Hypergraph.h"

using namespace std;
static const string kBOS = "<s>";
static const string kEOS = "</s>";

namespace MosesTuning
{

StringPiece NextLine(util::FilePiece& from)
{
  StringPiece line;
  while ((line = from.ReadLine()).starts_with("#"));
  return line;
}

Vocab::Vocab() :  eos_( FindOrAdd(kEOS)), bos_(FindOrAdd(kBOS))
{
}

const Vocab::Entry &Vocab::FindOrAdd(const StringPiece &str)
{
#if BOOST_VERSION >= 104200
  Map::const_iterator i= map_.find(str, Hash(), Equals());
#else
  std::string copied_str(str.data(), str.size());
  Map::const_iterator i = map_.find(copied_str.c_str());
#endif
  if (i != map_.end()) return *i;
  char *copied = static_cast<char*>(piece_backing_.Allocate(str.size() + 1));
  memcpy(copied, str.data(), str.size());
  copied[str.size()] = 0;
  return *map_.insert(Entry(copied, map_.size())).first;
}

double_conversion::StringToDoubleConverter converter(double_conversion::StringToDoubleConverter::NO_FLAGS, NAN, NAN, "inf", "nan");

/**
 * Reads an incoming edge. Returns edge and source words covered.
**/
static pair<Edge*,size_t> ReadEdge(util::FilePiece &from, Graph &graph)
{
  Edge* edge = graph.NewEdge();
  StringPiece line = from.ReadLine(); //Don't allow comments within edge lists
  util::TokenIter<util::MultiCharacter> pipes(line, util::MultiCharacter(" ||| "));
  //Target
  for (util::TokenIter<util::SingleCharacter, true> i(*pipes, util::SingleCharacter(' ')); i; ++i) {
    StringPiece got = *i;
    if ('[' == *got.data() && ']' == got.data()[got.size() - 1]) {
      // non-terminal
      char *end_ptr;
      unsigned long int child = std::strtoul(got.data() + 1, &end_ptr, 10);
      UTIL_THROW_IF(end_ptr != got.data() + got.size() - 1, HypergraphException, "Bad non-terminal" << got);
      UTIL_THROW_IF(child >= graph.VertexSize(), HypergraphException, "Reference to vertex " << child << " but we only have " << graph.VertexSize() << " vertices.  Is the file in bottom-up format?");
      edge->AddWord(NULL);
      edge->AddChild(child);
    } else {
      const Vocab::Entry &found = graph.MutableVocab().FindOrAdd(got);
      edge->AddWord(&found);
    }
  }

  //Features
  ++pipes;
  for (util::TokenIter<util::SingleCharacter, true> i(*pipes, util::SingleCharacter(' ')); i; ++i) {
    StringPiece fv = *i;
    if (!fv.size()) break;
    size_t equals = fv.find_last_of("=");
    UTIL_THROW_IF(equals == fv.npos, HypergraphException, "Failed to parse feature '" << fv << "'");
    StringPiece name = fv.substr(0,equals);
    StringPiece value = fv.substr(equals+1);
    int processed;
    float score = converter.StringToFloat(value.data(), value.length(), &processed);
    UTIL_THROW_IF(isnan(score), HypergraphException, "Failed to parse weight '" << value << "'");
    edge->AddFeature(name,score);
  }
  //Covered words
  ++pipes;
  size_t sourceCovered = boost::lexical_cast<size_t>(*pipes);
  return pair<Edge*,size_t>(edge,sourceCovered);
}

void Graph::Prune(Graph* pNewGraph, const SparseVector& weights, size_t minEdgeCount) const
{

  Graph& newGraph = *pNewGraph;
  //TODO: Optimise case where no pruning required

  //For debug

  /*
  map<const Edge*, string> edgeIds;
  for (size_t i = 0; i < edges_.Size(); ++i) {
    stringstream str;
    size_t childId = 0;
    for (size_t j = 0; j < edges_[i].Words().size(); ++j) {
      if (edges_[i].Words()[j]) {
        str << edges_[i].Words()[j]->first << " ";
      } else {
        str << "[" << edges_[i].Children()[childId++] << "] ";
      }
    }
    edgeIds[&(edges_[i])] = str.str();
  }
  */

  //end For debug

  map<const Edge*, FeatureStatsType> edgeBackwardScores;
  map<const Edge*, size_t> edgeHeads;
  vector<FeatureStatsType> vertexBackwardScores(vertices_.Size(), kMinScore);
  vector<vector<const Edge*> > outgoing(vertices_.Size());

  //Compute backward scores
  for (size_t vi = 0; vi < vertices_.Size(); ++vi) {
    // cerr << "Vertex " << vi << endl;
    const Vertex& vertex = vertices_[vi];
    const vector<const Edge*>& incoming = vertex.GetIncoming();
    if (!incoming.size()) {
      vertexBackwardScores[vi] = 0;
    } else {
      for (size_t ei = 0; ei < incoming.size(); ++ei) {
        //cerr << "Edge " << edgeIds[incoming[ei]] << endl;
        edgeHeads[incoming[ei]]= vi;
        FeatureStatsType incomingScore = incoming[ei]->GetScore(weights);
        for (size_t i = 0; i < incoming[ei]->Children().size(); ++i) {
          //cerr << "\tChild " << incoming[ei]->Children()[i] << endl;
          size_t childId = incoming[ei]->Children()[i];
          UTIL_THROW_IF(vertexBackwardScores[childId] == kMinScore,
                        HypergraphException, "Graph was not topologically sorted. curr=" << vi << " prev=" << childId);
          outgoing[childId].push_back(incoming[ei]);
          incomingScore += vertexBackwardScores[childId];
        }
        edgeBackwardScores[incoming[ei]]= incomingScore;
        //cerr << "Backward score: " << incomingScore << endl;
        if (incomingScore > vertexBackwardScores[vi]) vertexBackwardScores[vi] = incomingScore;
      }
    }
  }

  //Compute forward scores
  vector<FeatureStatsType> vertexForwardScores(vertices_.Size(), kMinScore);
  map<const Edge*, FeatureStatsType> edgeForwardScores;
  for (size_t i = 1; i <= vertices_.Size(); ++i) {
    size_t vi = vertices_.Size() - i;
    //cerr << "Vertex " << vi << endl;
    if (!outgoing[vi].size()) {
      vertexForwardScores[vi] = 0;
    } else {
      for (size_t ei = 0; ei < outgoing[vi].size(); ++ei) {
        //cerr << "Edge " << edgeIds[outgoing[vi][ei]] << endl;
        FeatureStatsType outgoingScore = 0;
        //add score of head
        outgoingScore += vertexForwardScores[edgeHeads[outgoing[vi][ei]]];
        //cerr << "Forward score " << outgoingScore << endl;
        edgeForwardScores[outgoing[vi][ei]] = outgoingScore;
        //sum scores of siblings
        for (size_t i = 0; i < outgoing[vi][ei]->Children().size(); ++i) {
          size_t siblingId = outgoing[vi][ei]->Children()[i];
          if (siblingId != vi) {
            //cerr << "\tSibling " << siblingId << endl;
            outgoingScore += vertexBackwardScores[siblingId];
          }
        }
        outgoingScore += outgoing[vi][ei]->GetScore(weights);
        if (outgoingScore > vertexForwardScores[vi]) vertexForwardScores[vi] = outgoingScore;
        //cerr << "Vertex " << vi << " forward score " << outgoingScore << endl;
      }
    }
  }

  multimap<FeatureStatsType, const Edge*> edgeScores;
  for (size_t i = 0; i < edges_.Size(); ++i) {
    const Edge* edge = &(edges_[i]);
    if (edgeForwardScores.find(edge) == edgeForwardScores.end()) {
      //This edge has no children, so didn't get a forward score. Its forward score
      //is that of its head
      edgeForwardScores[edge] = vertexForwardScores[edgeHeads[edge]];
    }
    FeatureStatsType score = edgeForwardScores[edge] + edgeBackwardScores[edge];
    edgeScores.insert(pair<FeatureStatsType, const Edge*>(score,edge));
    //  cerr << edgeIds[edge] << " " << score << endl;
  }

  multimap<FeatureStatsType, const Edge*>::const_reverse_iterator ei = edgeScores.rbegin();
  size_t edgeCount = 1;
  while(edgeCount < minEdgeCount && ei != edgeScores.rend()) {
    ++ei;
    ++edgeCount;
  }
  multimap<FeatureStatsType, const Edge*>::const_iterator lowest = edgeScores.begin();
  if (ei != edgeScores.rend())  lowest = edgeScores.lower_bound(ei->first);

  //cerr << "Retained edges" << endl;
  set<size_t> retainedVertices;
  set<const Edge*> retainedEdges;
  for (; lowest != edgeScores.end(); ++lowest) {
    //cerr << lowest->first << " " << edgeIds[lowest->second] << endl;
    retainedEdges.insert(lowest->second);
    retainedVertices.insert(edgeHeads[lowest->second]);
    for (size_t i = 0; i < lowest->second->Children().size(); ++i) {
      retainedVertices.insert(lowest->second->Children()[i]);
    }
  }
  newGraph.SetCounts(retainedVertices.size(), retainedEdges.size());

  //cerr << "Retained vertices" << endl;
  map<size_t,size_t> oldIdToNew;
  size_t vi = 0;
  for (set<size_t>::const_iterator i = retainedVertices.begin(); i != retainedVertices.end(); ++i, ++vi) {
//   cerr << *i << " New: " << vi << endl;
    oldIdToNew[*i] = vi;
    Vertex* vertex = newGraph.NewVertex();
    vertex->SetSourceCovered(vertices_[*i].SourceCovered());
  }

  for (set<const Edge*>::const_iterator i = retainedEdges.begin(); i != retainedEdges.end(); ++i) {
    Edge* newEdge = newGraph.NewEdge();
    const Edge* oldEdge = *i;
    for (size_t j = 0; j < oldEdge->Words().size(); ++j) {
      newEdge->AddWord(oldEdge->Words()[j]);
    }
    for (size_t j = 0; j < oldEdge->Children().size(); ++j) {
      newEdge->AddChild(oldIdToNew[oldEdge->Children()[j]]);
    }
    newEdge->SetFeatures(oldEdge->Features());
    Vertex& newHead = newGraph.vertices_[oldIdToNew[edgeHeads[oldEdge]]];
    newHead.AddEdge(newEdge);
  }

  /*
  cerr << "New graph" << endl;
  for (size_t vi = 0; vi < newGraph.VertexSize(); ++vi) {
    cerr << "Vertex " << vi << endl;
    const vector<const Edge*> incoming = newGraph.GetVertex(vi).GetIncoming();
    for (size_t ei = 0; ei < incoming.size(); ++ei) {
      size_t childId = 0;
      for (size_t wi = 0; wi < incoming[ei]->Words().size(); ++wi) {
        const Vocab::Entry* word = incoming[ei]->Words()[wi];
        if (word) {
          cerr << word->first << " ";
        } else {
          cerr << "[" << incoming[ei]->Children()[childId++] << "] ";
        }
      }
      cerr << " Score: " << incoming[ei]->GetScore(weights) <<  endl;
    }
    cerr << endl;
  }

  */

}

/**
  * Read from "Kenneth's hypergraph" aka cdec target_graph format (with comments)
**/
void ReadGraph(util::FilePiece &from, Graph &graph)
{

  //First line should contain field names
  StringPiece line = from.ReadLine();
  UTIL_THROW_IF(line.compare("# target ||| features ||| source-covered") != 0, HypergraphException, "Incorrect format spec on first line: '" << line << "'");
  line = NextLine(from);

  //Then expect numbers of vertices
  util::TokenIter<util::SingleCharacter, false> i(line, util::SingleCharacter(' '));
  unsigned long int vertices = boost::lexical_cast<unsigned long int>(*i);
  ++i;
  unsigned long int edges = boost::lexical_cast<unsigned long int>(*i);
  graph.SetCounts(vertices, edges);
  //cerr << "vertices: " << vertices << "; edges: " << edges << endl;
  for (size_t i = 0; i < vertices; ++i) {
    line = NextLine(from);
    unsigned long int edge_count = boost::lexical_cast<unsigned long int>(line);
    Vertex* vertex = graph.NewVertex();
    for (unsigned long int e = 0; e < edge_count; ++e) {
      pair<Edge*,size_t> edge = ReadEdge(from, graph);
      vertex->AddEdge(edge.first);
      //Note: the file format attaches this to the edge, but it's really a property
      //of the vertex.
      if (!e) {
        vertex->SetSourceCovered(edge.second);
      }
    }
  }
}

};

max_issues_repo_name: Pangeamt/nectm

max_forks_repo_name: Pangeamt/nectm


text:
/* Copyright (C) 2012-2019 IBM Corp.
 * This program is Licensed under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *   http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. See accompanying LICENSE file.
 */
#include <helib/hypercube.h>
#include <iomanip>
#include <NTL/lzz_p.h>

namespace helib {

  //! Break an index into the hypercube to index of the
  //! dimension-dim subcube and index inside that subcube.
std::pair<long,long> CubeSignature::breakIndexByDim(long idx, long dim) const
{
  std::pair<long,long> ans;
  ans.first = (idx%prods[dim+1]) + (idx/prods[dim])*prods[dim+1];
  ans.second = (idx % prods[dim]) / prods[dim+1];
  return ans;
}

   //! The inverse of breakIndexByDim
long CubeSignature::assembleIndexByDim(std::pair<long,long> idx, long dim) const
{
  long third = idx.first % prods[dim+1];
  idx.first = (idx.first - third) * dims[dim];
  return idx.first + idx.second*prods[dim+1] + third;
}

// Rotate k positions along the d'th dimension: The content of slot j that has
// coordinate j_d in the d'th dimension is moved to j' that has coordinates the
// same as j in all the dimensions except d, and has coordinate at dimension d
// j'_d = j_d +k mod sz (where sz is the size of the d'th dimension).
template<class T>
void HyperCube<T>::rotate1D(long d, long k)
{
  //OLD: assert(d >=0 && d < getNumDims());
  helib::assertInRange(d, 0l, getNumDims(), "d must be between 0 and number of dimensions", true);

  // Make sure rotation amount is in the range [1,dimSize-1]
  k %= getDim(d);
  if (k == 0) return;
  if (k < 0) k += getDim(d);

  // A simple implementation with a temporary vector
  NTL::Vec<T> tmp(NTL::INIT_SIZE, getSize());
  for (long i=0; i<getSize(); i++)
    tmp[addCoord(i, d, k)] = data[i];
  for (long i=0; i<getSize(); i++)
    data[i] = tmp[i];
}

// Shift k positions along the d'th dimension with zero fill
template<class T>
void HyperCube<T>::shift1D(long d, long k)
{
  //OLD: assert(d >=0 && d < getNumDims());
  helib::assertInRange(d, 0l, getNumDims(), "d must be between 0 and number of dimensions");

  // Make sure rotation amount is in the range [1,dimSize-1]
  bool negative = (k<0);
  k %= getDim(d);
  if (k == 0) return;
  if (k < 0) k += getDim(d);

  if (negative) { // left shift, zeros at the end
    for (long i=getSize()-1; i>=0; i--) {
      long iPrime = addCoord(i, d, k);
      if (iPrime < i) data[iPrime] = data[i];
      else            data[iPrime] = T(); // empty
    }
  } else {        // right shift, zeros at the beginning
    for (long i=0; i<getSize(); i++) {
      long iPrime = addCoord(i, d, k);
      if (iPrime > i) data[iPrime] = data[i];
      else            data[iPrime] = T(); // empty
    }
  }
}

// initialize the slice to point to the i-th subcube
// of the cube pointed to by bigger
template<class T>
ConstCubeSlice<T>::ConstCubeSlice(const ConstCubeSlice<T>& bigger, long i,
				  long dOffset)
{
  //OLD: assert(dOffset >= 0 && dOffset <= bigger.getNumDims());
  helib::assertInRange(dOffset, 0l, bigger.getNumDims(), "dOffset must be between 0 and bigger.getNumDims()", true);
  // allow zero-dimensional slice

  //OLD: assert(i >= 0 && i < bigger.getProd(0, dOffset));
  helib::assertInRange(i, 0l, bigger.getProd(0, dOffset), "i must be between 0 and bigger.getProd(0, dOffset)");

   data = bigger.data;
   sig = bigger.sig;
   dimOffset = dOffset + bigger.dimOffset;
   sizeOffset = bigger.sizeOffset + i*bigger.getProd(dOffset);
}

template<class T>
ConstCubeSlice<T>::ConstCubeSlice(const HyperCube<T>& _cube, long i,
				  long dOffset)
{
  //OLD: assert(dOffset >= 0 && dOffset <= _cube.getNumDims()); // allow zero-dimensional slice
  helib::assertInRange(dOffset, 0l, _cube.getNumDims(), "dOffset must be non-negative and at most _cube.getNumDims()", true);
  //OLD: assert(i >= 0 && i < _cube.getProd(0,dOffset));
  helib::assertInRange(i, 0l, _cube.getProd(0, dOffset), "i must be non-negative and at most _cube.getProd(0, dOffset)");

   data = &_cube.getData();
   sig = &_cube.getSig();
   dimOffset = dOffset;
   sizeOffset = i*_cube.getProd(dimOffset);
}

// deep copy of a slice: copies other into this
template<class T>
void CubeSlice<T>::copy(const ConstCubeSlice<T>& other) const
{
   long n = this->getSize();

   // we only check that the sizes match
   //OLD: assert(n == other.getSize());
   helib::assertEq(n, other.getSize(), "Cube sizes do not match");

   T *dst = &(*this)[0];
   const T *src = &other[0];

   for (long i = 0; i < n; i++)
      dst[i] = src[i];
}

// getHyperColumn reads out a (multi-dimensional) column from
// a slice.  The parameter pos specifies the position of the column,
// which must be in the range 0 <= pos < s.getProd(1).
// The vector v is filled with values whose coordinate in the lower
// dimensional subcube is equal to pos.  The length of v will be
// set to s.getDim(0).

template<class T>
void getHyperColumn(NTL::Vec<T>& v, const ConstCubeSlice<T>& s, long pos)
{
   long m = s.getProd(1);
   long n = s.getDim(0);

   //OLD: assert(pos >= 0 && pos < m);
   helib::assertInRange(pos, 0l, m, "pos must be between 0 and s.getProd(1)");
   v.SetLength(n);

   T* vp = &v[0];
   const T* sp = &s[0];

   for (long i = 0; i < n; i++)
      vp[i] = sp[pos + i*m];
}

// setHyperColumn does the reverse of getHyperColumn, setting the column
// to the given vector

template<class T>
void setHyperColumn(const NTL::Vec<T>& v, const CubeSlice<T>& s, long pos)
{
   long m = s.getProd(1);
   long n = s.getDim(0);

   //OLD: assert(pos >= 0 && pos < m);
   helib::assertInRange(pos, 0l, m, "pos must be between 0 and s.getProd(1)");
   if (v.length() < n) n = v.length();

   const T* vp = &v[0];
   T* sp = &s[0];

   for (long i = 0; i < n; i++)
      sp[pos + i*m] = vp[i];
}

// this version of setHyperColumn implicitly pads v with a default value,
// if v is too short

template<class T>
void setHyperColumn(const NTL::Vec<T>& v, const CubeSlice<T>& s, long pos, const T& val)
{
   long m = s.getProd(1);
   long n = s.getDim(0);
   long n1 = n;

   //OLD: assert(pos >= 0 && pos < m);
   helib::assertInRange(pos, 0l, m, "pos must be between 0 and s.getProd(1)");
   if (v.length() < n) n1 = v.length();

   const T* vp = &v[0];
   T* sp = &s[0];

   for (long i = 0; i < n1; i++)
      sp[pos + i*m] = vp[i];

   for (long i = n1; i < n; i++)
      sp[pos + i*m] = val;
}

template<class T>
void print3D(const HyperCube<T>& c)
{
   //OLD: assert(c.getNumDims() == 3);
  helib::assertEq(c.getNumDims(), 3l, "Cube must be 3-dimensional for call to print3D");

   ConstCubeSlice<T> s0(c);

   for (long i = 0; i < s0.getDim(0); i++) {

      ConstCubeSlice<T> s1(s0, i);
      for (long j = 0; j < s1.getDim(0); j++) {

         ConstCubeSlice<T> s2(s1, j);
         for (long k = 0; k < s2.getDim(0); k++)
            std::cout << std::setw(3) << s2.at(k);

         std::cout << "\n";
      }

      std::cout << "\n";
   }
}

// Explicit instantiations for long and for zz_p
template class HyperCube<long>;
template class ConstCubeSlice<long>;
template class CubeSlice<long>;
template void getHyperColumn(NTL::Vec<long>& v, const ConstCubeSlice<long>& s, long pos);
template void setHyperColumn(const NTL::Vec<long>& v, const CubeSlice<long>& s, long pos);
template void setHyperColumn(const NTL::Vec<long>& v, const CubeSlice<long>& s, long pos, const long& val);
template void print3D(const HyperCube<long>& c);

template class HyperCube<NTL::zz_p>;
template class ConstCubeSlice<NTL::zz_p>;
template class CubeSlice<NTL::zz_p>;
template void getHyperColumn(NTL::Vec<NTL::zz_p>& v, const ConstCubeSlice<NTL::zz_p>& s, long pos);
template void setHyperColumn(const NTL::Vec<NTL::zz_p>& v, const CubeSlice<NTL::zz_p>& s, long pos);
template void setHyperColumn(const NTL::Vec<NTL::zz_p>& v, const CubeSlice<NTL::zz_p>& s, long pos, const NTL::zz_p& val);
template void print3D(const HyperCube<NTL::zz_p>& c);

}

max_stars_repo_name: lparth/homeenc-HElib

max_issues_repo_name: lparth/homeenc-HElib

max_forks_repo_name: lparth/homeenc-HElib


text: #include <boost/fusion/include/fold.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/******************************************************************************
 * Author(s): Christopher J. Havlicek
 *
 * See LICENSE and CONTACTS.
 ******************************************************************************/
#include "../../master.hpp"

#include <boost/test/unit_test.hpp>

namespace utf = boost::unit_test;

namespace kmap::test {

/******************************************************************************/
BOOST_AUTO_TEST_SUITE( cli )
/******************************************************************************/
BOOST_AUTO_TEST_SUITE( parse_raw )
/******************************************************************************/
BOOST_AUTO_TEST_SUITE( tag
                     ,
                     * utf::disabled() ) // TODO: Re-enable test suite. Temporary disabled until reassessment of feature.
/******************************************************************************/
BOOST_AUTO_TEST_CASE( misc
                    ,
                    * utf::depends_on( "kmap_iface" )
                    * utf::depends_on( "network" )
                    * utf::fixture< ClearMapFixture >() )
{
    auto& kmap = Singleton::instance();
    auto& cli = kmap.cli();

    create_lineages( "1"
                   , "2" );

    // create tags.t_1
    BOOST_TEST( cli.parse_raw( ":create.tag t_1" )  );
    BOOST_TEST( cli.parse_raw( ":create.tag t_1" )  );
    BOOST_TEST( cli.parse_raw( ":create.tag: T 1" )  );
    BOOST_TEST( kmap.fetch_heading( kmap.selected_node() ).value() == "t_1" );
    BOOST_TEST( kmap.absolute_path_flat( kmap.selected_node() ) == "/tags.t_1" );
    // create tags.indirection.t_1
    BOOST_TEST( cli.parse_raw( ":create.tag indirection.t_1" )  );
    BOOST_TEST( kmap.absolute_path_flat( kmap.selected_node() ) == "/tags.indirection.t_1" );
    // make t_1.indirection a tag of .root.a
    BOOST_TEST( cli.parse_raw( ":select.node .root.1" )  );
    BOOST_TEST( cli.parse_raw( ":add.tag t_1.indirection" )  );
    BOOST_TEST( cli.parse_raw( ":add.tag t_1.indirection" )  );
    BOOST_TEST( cli.parse_raw( ":add.tag t_1" )  ); // An alias of heading "t_1" already exists.
    BOOST_TEST( kmap.absolute_path_flat( kmap.selected_node() ) == "/1" );
    // make t_1 a tag of .root.b
    BOOST_TEST( cli.parse_raw( ":select.node .root.2" )  );
    BOOST_TEST( cli.parse_raw( ":add.tag t_1" )  );
    BOOST_TEST( cli.parse_raw( ":add.tag t_1" )  ); // Duplicate alias.
    BOOST_TEST( cli.parse_raw( ":add.tag t_1.indirection" )  ); // An alias of heading "t_1" already exists.
    BOOST_TEST( kmap.absolute_path_flat( kmap.selected_node() ) == "/2" );
}

BOOST_AUTO_TEST_SUITE_END( /* tag */ )
BOOST_AUTO_TEST_SUITE_END( /* parse_raw */ )
BOOST_AUTO_TEST_SUITE_END( /* cli */ )

} // namespace kmap::test

max_stars_repo_name: moralismercatus/kmap

max_issues_repo_name: moralismercatus/kmap

max_forks_repo_name: moralismercatus/kmap


text: #include <boost/hana/prefix.hpp>


text:
// message.hpp

// Boost Logging library
//
// Author: John Torjo, www.torjo.com
//
// Copyright (C) 2007 John Torjo (see www.torjo.com for email)
//
//  SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
// See http://www.torjo.com/log2/ for more details

#pragma once

#include <hpx/config.hpp>
#include <hpx/modules/format.hpp>
#include <hpx/type_support/unused.hpp>

#include <boost/utility/string_ref.hpp>

#include <cstddef>
#include <sstream>
#include <string>
#include <utility>

namespace hpx { namespace util { namespace logging {

    /**
        @brief Optimizes the formatting for prepending and/or appending strings to
        the original message

        It keeps all the modified message in one string.
        Useful if some formatter needs to access the whole
        string at once.

        reserve() - the size that is reserved for prepending
        (similar to string::reserve function)

        Note : as strings are prepended, reserve() shrinks.
    */
    class message
    {
    public:
        message()
          : m_full_msg_computed(false)
        {
        }

        /**
        @param msg - the message that is originally cached
         */
        explicit message(std::stringstream msg)
          :
#if defined(HPX_COMPUTE_HOST_CODE)
          m_str(std::move(msg))
          ,
#endif
          m_full_msg_computed(false)
        {
#if !defined(HPX_COMPUTE_HOST_CODE)
            HPX_UNUSED(msg);
#endif
        }

        message(message&& other) noexcept
          :
#if defined(HPX_COMPUTE_HOST_CODE)
          m_str(std::move(other.m_str))
          ,
#endif
          m_full_msg_computed(other.m_full_msg_computed)
#if defined(HPX_COMPUTE_HOST_CODE)
          , m_full_msg(std::move(other.m_full_msg))
#endif
        {
            other.m_full_msg_computed = false;
        }

        template <typename T>
        message& operator<<(T&& v)
        {
            m_str << std::forward<T>(v);
            m_full_msg_computed = false;
            return *this;
        }

        template <typename... Args>
        message& format(
            boost::string_ref format_str, Args const&... args) noexcept
        {
            util::format_to(m_str, format_str, args...);
            m_full_msg_computed = false;
            return *this;
        }

        /**
            returns the full string
        */
        std::string const& full_string() const
        {
            if (!m_full_msg_computed)
            {
                m_full_msg_computed = true;
                m_full_msg = m_str.str();
            }
            return m_full_msg;
        }

        bool empty() const
        {
            return full_string().empty();
        }

        friend std::ostream& operator<<(std::ostream& os, message const& value)
        {
            return os << value.m_str.rdbuf();
        }

    private:
        std::stringstream m_str;

        // caching
        mutable bool m_full_msg_computed;
        mutable std::string m_full_msg;
    };
}}}    // namespace hpx::util::logging


text: #include <boost/thread/lock_concepts.hpp>


text:
#include "SymplecticEuler.h"
#include <Eigen/LU>
#include <Eigen/Core>

bool SymplecticEuler::stepScene( TwoDScene& scene, scalar dt )
{
    VectorXs& qn = scene.getX();
    VectorXs& qn1 = qn;
    VectorXs& qdotn = scene.getV();
    VectorXs& qdotn1 = qdotn;
    const VectorXs& m = scene.getM();
    MatrixXs M = m.asDiagonal();
    MatrixXs MMinus1 = M.inverse();

	//Symplectic Euler
    VectorXs deltaU = VectorXs::Zero(qn.size());
    VectorXs& f = deltaU;
    scene.accumulateGradU(deltaU);
	f = -1*deltaU;

    qdotn1 = qdotn + dt*MMinus1*f;

    for(int i = 0; i < scene.getNumParticles(); ++i)
        if(scene.isFixed(i))
            scene.setVelocity(i, {0,0});

    qn1 = qn + dt*qdotn1;

    return true;
}

max_stars_repo_name: xunilrj/sandbox

max_issues_repo_name: xunilrj/sandbox

max_forks_repo_name: xunilrj/sandbox


text:
#include <cstdint>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <vector>

#include <boost/property_tree/ptree.hpp>

#include "baldr/json.h"
#include "midgard/logging.h"

#include "midgard/util.h"
#include "odin/directionsbuilder.h"
#include "odin/util.h"
#include "odin/worker.h"
#include "tyr/serializers.h"

#include "proto/trip.pb.h"

using namespace valhalla;
using namespace valhalla::tyr;
using namespace valhalla::midgard;
using namespace valhalla::baldr;

namespace valhalla {
namespace odin {

odin_worker_t::odin_worker_t(const boost::property_tree::ptree&) {
}

odin_worker_t::~odin_worker_t() {
}

void odin_worker_t::cleanup() {
}

void odin_worker_t::narrate(Api& request) const {
  // time this whole method and save that statistic
  auto _ = measure_scope_time(request, "odin_worker_t::narrate");

  // get some annotated directions
  try {
    odin::DirectionsBuilder().Build(request);
  } catch (...) { throw valhalla_exception_t{202}; }
}

void odin_worker_t::status(Api&) const {
#ifdef HAVE_HTTP
  // if we are in the process of shutting down we signal that here
  // should react by draining traffic (though they are likely doing this as they are usually the ones
  // who sent us the request to shutdown)
  if (prime_server::draining() || prime_server::shutting_down()) {
    throw valhalla_exception_t{203};
  }
#endif
}

#ifdef HAVE_HTTP
prime_server::worker_t::result_t
odin_worker_t::work(const std::list<zmq::message_t>& job,
                    void* request_info,
                    const std::function<void()>& interrupt_function) {
  auto& info = *static_cast<prime_server::http_request_info_t*>(request_info);
  LOG_INFO("Got Odin Request " + std::to_string(info.id));
  Api request;
  try {
    // Set the interrupt function
    service_worker_t::set_interrupt(&interrupt_function);

    // crack open the in progress request
    bool success = request.ParseFromArray(job.front().data(), job.front().size());
    if (!success) {
      LOG_ERROR("Failed parsing pbf in Odin::Worker");
      throw valhalla_exception_t{200,
                                 boost::optional<std::string>("Failed parsing pbf in Odin::Worker")};
    }

    // its either a simple status request or its a route to narrate
    switch (request.options().action()) {
      case Options::status: {
        status(request);
        auto response = tyr::serializeStatus(request);
        return to_response(response, info, request);
      }
      default: {
        // narrate them and serialize them along
        narrate(request);
        auto response = tyr::serializeDirections(request);
        const bool as_gpx = request.options().format() == Options::gpx;
        return to_response(response, info, request, as_gpx ? worker::GPX_MIME : worker::JSON_MIME,
                           as_gpx);
      }
    }
  } catch (const std::exception& e) {
    return jsonify_error({299, std::string(e.what())}, info, request);
  }
}

void run_service(const boost::property_tree::ptree& config) {
  // gracefully shutdown when asked via SIGTERM
  prime_server::quiesce(config.get<unsigned int>("httpd.service.drain_seconds", 28),
                        config.get<unsigned int>("httpd.service.shutting_seconds", 1));

  // gets requests from odin proxy
  auto upstream_endpoint = config.get<std::string>("odin.service.proxy") + "_out";
  // or returns just location information back to the server
  auto loopback_endpoint = config.get<std::string>("httpd.service.loopback");
  auto interrupt_endpoint = config.get<std::string>("httpd.service.interrupt");

  // listen for requests
  zmq::context_t context;
  prime_server::worker_t worker(context, upstream_endpoint, "ipc:///dev/null", loopback_endpoint,
                                interrupt_endpoint,
                                std::bind(&odin_worker_t::work, odin_worker_t(config),
                                          std::placeholders::_1, std::placeholders::_2,
                                          std::placeholders::_3));
  worker.work();

  // TODO: should we listen for SIGINT and terminate gracefully/exit(0)?
}

#endif
} // namespace odin
} // namespace valhalla

ext: cc

max_stars_repo_name: mesozoic-drones/valhalla

max_issues_repo_name: mesozoic-drones/valhalla

max_forks_repo_name: mesozoic-drones/valhalla


text:
#include <pxp-agent/modules/apply.hpp>
#include <pxp-agent/util/bolt_helpers.hpp>
#include <pxp-agent/configuration.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/tokenizer.hpp>
#include <leatherman/json_container/json_container.hpp>
#include <leatherman/file_util/file.hpp>
#include <leatherman/locale/locale.hpp>

namespace fs = boost::filesystem;
namespace lth_file = leatherman::file_util;
namespace lth_jc   = leatherman::json_container;
namespace lth_loc  = leatherman::locale;

namespace PXPAgent {
namespace Modules {

    static const std::string apply_ACTION { "apply" };
    static const std::string apply_ACTION_INPUT_SCHEMA { R"(
    {
        "type": "object",
        "properties": {
            "catalog": {
                "type": "object"
            },
            "apply_options": {
                "type": "object"
            }
        },
        "required": ["catalog", "apply_options"]
    }
    )" };

    static const std::string prep_ACTION { "prep" };

    // TODO: Actually manage this file in packaging (or perhaps fetch it from puppetserver).
    // For now just copy it to the cache dir each time unless there is already a copy
    static const std::string APPLY_RUBY_SHIM {
R"(#! /opt/puppetlabs/puppet/bin/ruby
# frozen_string_literal: true

require 'fileutils'
require 'json'
require 'puppet'
require 'puppet/configurer'
require 'securerandom'
require 'tempfile'
require 'uri'

## TODO: Option to read from a file is for debugging. Only read from stdin in production.
args = JSON.parse(ARGV[0] ? File.read(ARGV[0]) : STDIN.read)

# Create temporary directories for all core Puppet settings so we don't clobber
# existing state or read from puppet.conf. Also create a temporary modulepath.
# Additionally include rundir, which gets its own initialization.
puppet_root = Dir.mktmpdir
moduledir = File.join(puppet_root, 'modules')
Dir.mkdir(moduledir)
plugin_cache = args['plugin_cache']
plugin_dest = File.join(plugin_cache, 'plugins')
pluginfact_dest = File.join(plugin_cache, 'pluginfacts')
# Use isolated directories in puppet_root
setting_keys = Puppet::Settings::REQUIRED_APP_SETTINGS.append(:rundir)
cli_base = (setting_keys).flat_map do |setting|
  ["--#{setting}", File.join(puppet_root, setting.to_s.chomp('dir'))]
end
cli_base.concat([
  '--modulepath',
  moduledir,
  '--plugindest',
  plugin_dest,
  '--pluginfactdest',
  pluginfact_dest
])
# There will always be at least a single master URI
# TODO: make sure comma separated is what --server_list expects
server_list = args['master_uris'].map { |uri| URI.parse(uri).host }.join(',')

# These settings are required for communication with puppetserver. This is primarily for
# pluginsync but it is also required if a catalog requires files from modules served by
# puppetserver (Puppet[:default_file_terminus] = rest by default)
cli_settings_pluginsync = [
  '--localcacert',
  args['ca'],
  '--hostcert',
  args['crt'],
  '--hostprivkey',
  args['key'],
  '--hostcrl',
  args['crl'],
  '--server_list',
  server_list
]

# Break apart proxy and extract individual settings
proxy_flags = {
  user: '--http_proxy_user',
  password: '--http_proxy_password',
  port: '--http_proxy_port',
  host: '--http_proxy_host'
}
# Proxy will always be a string (even if its empty)
parsed_proxy = URI.parse(args['proxy'])
proxy_flags.each do |uri_method, setting_flag|
  val = parsed_proxy.send(uri_method)
  cli_settings_pluginsync << setting_flag << val unless val.nil?
end

exit_code = 0
begin

  Puppet.initialize_settings(cli_base + cli_settings_pluginsync)

  remote_env_for_plugins = Puppet::Node::Environment.remote(args['environment'])
  downloader = Puppet::Configurer::Downloader.new(
    "plugin",
    Puppet[:plugindest],
    Puppet[:pluginsource],
    Puppet[:pluginsignore],
    remote_env_for_plugins
  )
  downloader.evaluate

  source_permissions = Puppet::Util::Platform.windows? ? :ignore : :use
  plugin_fact_downloader = Puppet::Configurer::Downloader.new(
    "pluginfacts",
    Puppet[:pluginfactdest],
    Puppet[:pluginfactsource],
    Puppet[:pluginsignore],
    remote_env_for_plugins,
    source_permissions
  )
  plugin_fact_downloader.evaluate

  # Append the newe paths to the load path (copying them over to the new vardir takes time and seems unneeded)
  $LOAD_PATH << plugin_dest << pluginfact_dest

  # Avoid extraneous output
  Puppet[:report] = false

  # apply_settings will always be a hash (even if it empty) who's keys are puppet settings
  # For example: `noop` or `show_diff`. (only applies to apply action)
  args['apply_options'].each { |setting, value| Puppet[setting.to_sym] = value } if args['action'] == 'apply'

  # This happens implicitly when running the Configurer, but we make it explicit here. It creates the
  # directories we configured earlier.
  Puppet.settings.use(:main)

  # Ensure custom facts are available for provider suitability tests
  facts = Puppet::Node::Facts.indirection.find(SecureRandom.uuid, environment: remote_env_for_plugins)

  if args['action'] == 'apply'

    report = Puppet::Transaction::Report.new

    overrides = { current_environment: remote_env_for_plugins,
                  loaders: Puppet::Pops::Loaders.new(remote_env_for_plugins) }

    Puppet.override(overrides) do
      catalog = Puppet::Resource::Catalog.from_data_hash(args['catalog'])
      catalog.environment = remote_env_for_plugins.name.to_s
      catalog.environment_instance = remote_env_for_plugins
      Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(facts, catalog)

      catalog = catalog.to_ral

      configurer = Puppet::Configurer.new
      configurer.run(catalog: catalog, report: report, pluginsync: false)
    end

    puts JSON.pretty_generate(report.to_data_hash)
    exit_code = report.exit_status != 1
  else
    facts.name = facts.values['clientcert']
    puts facts.values.to_json
  end
ensure
  begin
    FileUtils.remove_dir(puppet_root)
  rescue Errno::ENOTEMPTY => e
    STDERR.puts("Could not cleanup temporary directory: #{e}")
  end
end

exit exit_code
)" };

    Apply::Apply(const fs::path& exec_prefix,
                 const std::vector<std::string>& master_uris,
                 const std::string& ca,
                 const std::string& crt,
                 const std::string& key,
                 const std::string& crl,
                 const std::string& proxy,
                 std::shared_ptr<ModuleCacheDir> module_cache_dir,
                 std::shared_ptr<ResultsStorage> storage) :
        BoltModule { exec_prefix, std::move(storage), std::move(module_cache_dir) },
        Purgeable { module_cache_dir_->purge_ttl_ },
        master_uris_ { master_uris },
        ca_ { ca },
        crt_ { crt },
        key_ { key },
        crl_ { crl },
        proxy_ { proxy }
    {
        module_name = "apply";
        actions.push_back(apply_ACTION);
        actions.push_back(prep_ACTION);
        PCPClient::Schema apply_input_schema { apply_ACTION, lth_jc::JsonContainer { apply_ACTION_INPUT_SCHEMA } };
        input_validator_.registerSchema(apply_input_schema);

        PCPClient::Schema prep_input_schema { prep_ACTION };
        prep_input_schema.addConstraint("environment", PCPClient::TypeConstraint::String, true);
        input_validator_.registerSchema(prep_input_schema);

        PCPClient::Schema apply_output_schema { apply_ACTION };
        results_validator_.registerSchema(apply_output_schema);

        PCPClient::Schema prep_output_schema { prep_ACTION };
        results_validator_.registerSchema(prep_output_schema);
    }

    // This is copied here for now until we decide how to manage the ruby shim
    // NIX_DIR_PERMS is defined in pxp-agent/configuration
    #define NIX_DOWNLOADED_FILE_PERMS NIX_DIR_PERMS

    Util::CommandObject Apply::buildCommandObject(const ActionRequest& request)
    {
        if (crl_ == "") {
          throw Configuration::Error { lth_loc::format("ssl-crl setting is requried for apply") };
        }
        // Shared
        auto action = request.action();
        auto params = request.params();
        params.set<std::string>("ca", ca_);
        params.set<std::string>("crt", crt_);
        params.set<std::string>("key", key_);
        params.set<std::string>("crl", crl_);
        params.set<std::string>("proxy", proxy_);

        const fs::path& results_dir { request.resultsDir() };

        const std::string ruby_shim_cache_dir = "apply_ruby_shim";
        const fs::path& cache_dir = module_cache_dir_->createCacheDir(ruby_shim_cache_dir);

        std::string plugin_cache_name;

        const std::string ruby_shim_script_name = "apply_ruby_shim.rb";
        auto apply_ruby_shim_path = cache_dir / ruby_shim_script_name;

        if (!fs::exists(apply_ruby_shim_path)) {
          lth_file::atomic_write_to_file(APPLY_RUBY_SHIM, apply_ruby_shim_path.string(), NIX_DOWNLOADED_FILE_PERMS, std::ios::binary);
        }

        if (action == "apply") {
            plugin_cache_name = params.get<std::string>({"catalog", "environment"});
            params.set<std::string>("environment", params.get<std::string>({"catalog", "environment"}));
            params.set<std::string>("action", "apply");
        } else {
            plugin_cache_name = params.get<std::string>("environment");
            params.set<std::string>("action", "prep");
        }

        const auto plugin_cache = module_cache_dir_->createCacheDir(plugin_cache_name);
        params.set<std::string>("plugin_cache", plugin_cache.string());
        params.set<std::vector<std::string>>("master_uris", master_uris_);
        Util::CommandObject cmd {
            "",  // Executable will be detremined by findExecutableAndArguments
            {},  // No args for invoking shim
            {},  // Shim expects catalog on stdin
            params.toString(),  // JSON encoded string to be passed to shim on stdin
            [results_dir](size_t pid) {
                auto pid_file = (results_dir / "pid").string();
                lth_file::atomic_write_to_file(std::to_string(pid) + "\n", pid_file,
                                            NIX_FILE_PERMS, std::ios::binary);
            }  // PID Callback
        };
        Util::findExecutableAndArguments(apply_ruby_shim_path, cmd);

        return cmd;
    }

    unsigned int Apply::purge(
        const std::string& ttl,
        std::vector<std::string> ongoing_transactions,
        std::function<void(const std::string& dir_path)> purge_callback)
    {
        if (purge_callback == nullptr)
            purge_callback = &Purgeable::defaultDirPurgeCallback;
        return module_cache_dir_->purgeCache(ttl, ongoing_transactions, purge_callback);
    }

}  // namespace Modules
}  // namespace PXPAgent

max_stars_repo_name: barriserloth/pxp-agent

max_issues_repo_name: barriserloth/pxp-agent

max_forks_repo_name: barriserloth/pxp-agent


text:
// (C) Copyright Jonathan Turkanis 2004
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)

// See http://www.boost.org/libs/iostreams for documentation.

#include <fstream>
#include <boost/iostreams/device/file.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/tee.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include "detail/temp_file.hpp"
#include "detail/verification.hpp"

using namespace std;
using namespace boost;
using namespace boost::iostreams;
using namespace boost::iostreams::test;
using boost::unit_test::test_suite;

void tee_test()
{
    {
        temp_file          dest1;
        temp_file          dest2;
        filtering_ostream  out;
        out.push(tee(file_sink(dest1.name(), out_mode)));
        out.push(file_sink(dest2.name(), out_mode));
        write_data_in_chars(out);
        out.reset();
        BOOST_CHECK_MESSAGE(
            compare_files(dest1.name(), dest2.name()),
            "failed writing to a tee_filter in chars"
        );
    }

    {
        temp_file          dest1;
        temp_file          dest2;
        filtering_ostream  out;
        out.push(tee(file_sink(dest1.name(), out_mode)));
        out.push(file_sink(dest2.name(), out_mode));
        write_data_in_chunks(out);
        out.reset();
        BOOST_CHECK_MESSAGE(
            compare_files(dest1.name(), dest2.name()),
            "failed writing to a tee_filter in chunks"
        );
    }

    {
        temp_file          dest1;
        temp_file          dest2;
        filtering_ostream  out;
        out.push( tee( file_sink(dest1.name(), out_mode),
                       file_sink(dest2.name(), out_mode) ) );
        write_data_in_chars(out);
        out.reset();
        BOOST_CHECK_MESSAGE(
            compare_files(dest1.name(), dest2.name()),
            "failed writing to a tee_device in chars"
        );
    }

    {
        temp_file          dest1;
        temp_file          dest2;
        filtering_ostream  out;
        out.push( tee( file_sink(dest1.name(), out_mode),
                       file_sink(dest2.name(), out_mode) ) );
        write_data_in_chunks(out);
        out.reset();
        BOOST_CHECK_MESSAGE(
            compare_files(dest1.name(), dest2.name()),
            "failed writing to a tee_device in chunks"
        );
    }
}

test_suite* init_unit_test_suite(int, char* [])
{
    test_suite* test = BOOST_TEST_SUITE("tee test");
    test->add(BOOST_TEST_CASE(&tee_test));
    return test;
}

max_stars_repo_name: spxuw/RFIM

max_issues_repo_name: spxuw/RFIM

max_forks_repo_name: spxuw/RFIM