int main( )
{
    // Use Boost library to make a random number generator.
    boost::mt19937 randomNumbergenerator( time( 0 ) );
    boost::random::uniform_real_distribution< > uniformDistribution( 0.0, 10.0 );
    boost::variate_generator< boost::mt19937&, boost::random::uniform_real_distribution < > >
            generateRandomNumbers( randomNumbergenerator, uniformDistribution );

    // Generate random altitude value between 0 and 10 km.
    const double altitudeKilometers = generateRandomNumbers( );

    // Use the Tudat Core library to convert km to m.
    const double altitudeMeters = tudat::unit_conversions::convertKilometersToMeters(
            altitudeKilometers );

    // Use the Eigen library to create position vectors.
    Eigen::Vector3d positionOfBodySubjectToAcceleration;
    positionOfBodySubjectToAcceleration << 1737.1e3 + altitudeMeters, 0.0, 0.0;
    const Eigen::Vector3d positionOfBodyExertingAcceleration = Eigen::Vector3d::Zero( );

    // Use the Tudat library to compute the acceleration vector.
    const Eigen::Vector3d gravitationalAcceleration =
            tudat::gravitation::computeGravitationalAcceleration(
                    positionOfBodySubjectToAcceleration, 4.9e12,
                    positionOfBodyExertingAcceleration );

    // Print the altitude and norm of the acceleration vector.
    std::cout << "Hello world!" << std::endl;
    std::cout << "I am floating " << altitudeKilometers << " km above the Moon's surface." <<
            std::endl;
    std::cout << "The gravitational acceleration here is " <<
            gravitationalAcceleration.norm() << " m/s^2."  << std::endl;

    return 0;
}
void testMeanToHyperbolicEccentricAnomalyConversions(
        const std::string& caseId,
        const ScalarType testTolerance,
        const ScalarType meanAnomalyLimit,
        const bool useConstantEccentricity = 0,
        const bool useExponentialValues = 0,
        const ScalarType minimumEccentricity = TUDAT_NAN,
        const ScalarType maximumEccentricity = TUDAT_NAN,
        const ScalarType constantEccentricity = TUDAT_NAN,
        const int numberOfSamples = 1E5)
{
    // Create vectors that will store the input variables of a test that resulted in an error, such
    // that the error scenario can be reproduced.
    std::vector< double > failedMeanAnomalies, failedEccentricities;

    // Boolean that will be set true if a runtime error occurred.
    bool aRuntimeErrorOccurred = false;

    // Set test value for eccentricity.
    ScalarType testEccentricity = constantEccentricity;

    // Initialize both test and reverse calculated mean anomaly and the eccentric anomaly.
    ScalarType testMeanAnomaly, reverseCalculatedMeanAnomaly, eccentricAnomaly = 0.0;

    // Instantiate random number generator.
    boost::mt19937 randomNumbergenerator( time( 0 ) );

    // Create generator for eccentricity (only used if useConstantEccentricity is false).
    boost::random::uniform_real_distribution< > eccentricityDistribution;
    if( !useConstantEccentricity )
    {
        eccentricityDistribution =
                boost::random::uniform_real_distribution< >(
                    minimumEccentricity, maximumEccentricity );
    }


    boost::variate_generator< boost::mt19937&, boost::random::uniform_real_distribution < > >
            eccentricityGenerator(
                randomNumbergenerator, eccentricityDistribution );

    // Create generator for mean anomaly.
    boost::random::uniform_real_distribution< ScalarType > meanAnomalyDistibution(
                -meanAnomalyLimit, meanAnomalyLimit );
    boost::variate_generator<
            boost::mt19937&, boost::random::uniform_real_distribution < ScalarType > >
            generateMeanAnomaly( randomNumbergenerator, meanAnomalyDistibution );

    // Perform the conversion for the specified number of samples and test whether the values that
    // are subsequently converted back match the initial values.
    for ( int counter = 0; counter < numberOfSamples; counter++ )
    {
        // Set random value in test mean anomaly.
        testMeanAnomaly = generateMeanAnomaly( );

        if( useExponentialValues )
        {
            testMeanAnomaly = testMeanAnomaly *
                    std::pow( getFloatingInteger< ScalarType >( 10 ), generateMeanAnomaly( ) );
        }
        // If eccentricity is to be varied, generate random value
        if( !useConstantEccentricity )
        {
            testEccentricity = eccentricityGenerator( );

            if( useExponentialValues )
            {
                testEccentricity = getFloatingInteger< ScalarType >( 1 ) +
                        std::pow( getFloatingInteger< ScalarType >( 10 ), testEccentricity );
            }
        }

        // If the Rootfinder does not converge, it will produce a runtime error. In order to make
        // sure that these values that led to the error will not be lost, they will be stored in
        // the failed input data vectors. To do so, a try-catch sequence is used.
        try
        {
            // Compute eccentric anomaly.
            eccentricAnomaly = convertMeanAnomalyToHyperbolicEccentricAnomaly< ScalarType>(
                        testEccentricity, testMeanAnomaly );
        }
        catch( std::runtime_error )
        {
            // Store the fact that a runtime error occurred, such that the values will be stored.
            aRuntimeErrorOccurred = true;
        }

        // Calculate the mean anomaly from this eccentric anomaly.
        reverseCalculatedMeanAnomaly = convertHyperbolicEccentricAnomalyToMeanAnomaly< ScalarType>(
                    eccentricAnomaly, testEccentricity );

        // Test whether the computed mean anomaly is equal to the mean anomaly from the input and
        // that no runtime errors occurred. If an error was found, store the values leading to this
        // error in a vector for later use. '!' operator is there to ensure that a NaN value will
        // result in the values being written away. It is also checked that the mean anomaly is
        // not equal to 0.0, because that would result in falsely writing an error.
        if( !useExponentialValues )
        {
            if ( ( ( !( std::abs( testMeanAnomaly - reverseCalculatedMeanAnomaly ) <
                        testTolerance ) )
                   && !( testMeanAnomaly == getFloatingInteger< ScalarType >( 0 ) ||
                         reverseCalculatedMeanAnomaly == getFloatingInteger< ScalarType >( 0 ) ) )
                 && !aRuntimeErrorOccurred )
            {
                failedMeanAnomalies.push_back( testMeanAnomaly );
                failedEccentricities.push_back( testEccentricity );
            }
        }
        else
        {
            if ( ( ( !( std::abs( testMeanAnomaly - reverseCalculatedMeanAnomaly ) /
                        testMeanAnomaly < testTolerance ) )
                   && !( testMeanAnomaly == getFloatingInteger< ScalarType >( 0 ) ||
                         reverseCalculatedMeanAnomaly == getFloatingInteger< ScalarType >( 0 ) ) )
                 && !aRuntimeErrorOccurred )
            {
                failedMeanAnomalies.push_back( testMeanAnomaly );
                failedEccentricities.push_back( testEccentricity );
            }
        }

        // Reset boolean.
        aRuntimeErrorOccurred = false;
    }

    // Check that no values have been written to the failedMeanAnomalies vector.  If so, this test
    // is passed. Otherwisely these values will be written away and this test will fail.
    BOOST_CHECK( failedMeanAnomalies.empty( ) );

    // If the vector is not empty, write the failed cases of this test case to a file.
    if ( !( failedMeanAnomalies.empty( ) ) )
    {
        writeErrorsToFile( failedEccentricities, failedMeanAnomalies, caseId );
    }
}