<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "OsmNominatimRunner.h"

#include "MarbleAbstractRunner.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataExtendedData.h"
#include "TinyWebBrowser.h"

#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtCore/QUrl>
#include <QtCore/QTimer>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtXml/QDomDocument>

namespace Marble
{

OsmNominatimRunner::OsmNominatimRunner( QObject *parent ) :
    MarbleAbstractRunner( parent ), m_manager( new QNetworkAccessManager (this ) )
{
    connect(m_manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(handleResult(QNetworkReply*)));
}

OsmNominatimRunner::~OsmNominatimRunner()
{
    // nothing to do
}

GeoDataFeature::GeoDataVisualCategory OsmNominatimRunner::category() const
{
    return GeoDataFeature::OsmSite;
}

void OsmNominatimRunner::returnNoResults()
{
    emit searchFinished( QVector<GeoDataPlacemark*>() );
}

void OsmNominatimRunner::returnNoReverseGeocodingResult()
{
    emit reverseGeocodingFinished( m_coordinates, GeoDataPlacemark() );
}

void OsmNominatimRunner::search( const QString &searchTerm )
{
    QString base = "http://nominatim.openstreetmap.org/search?";
    QString query = "q=%1&format=xml&addressdetails=1&accept-language=%2";
    QString url = QString(base + query).arg(searchTerm).arg(MarbleLocale::languageCode());

    m_searchRequest.setUrl(QUrl(url));
    m_searchRequest.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "OsmNominatimRunner") );

    // @todo FIXME Must currently be done in the main thread, see bug 257376
    QTimer::singleShot( 0, this, SLOT( startSearch() ) );
}

void OsmNominatimRunner::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    m_coordinates = coordinates;
    QString base = "http://nominatim.openstreetmap.org/reverse?format=xml&addressdetails=1";
    // @todo: Alternative URI with addressdetails=1 could be used for shorther placemark name
    QString query = "&lon=%1&lat=%2&accept-language=%3";
    double lon = coordinates.longitude( GeoDataCoordinates::Degree );
    double lat = coordinates.latitude( GeoDataCoordinates::Degree );
    QString url = QString( base + query ).arg( lon ).arg( lat ).arg( MarbleLocale::languageCode() );

    m_reverseGeocodingRequest.setUrl(QUrl(url));
    m_reverseGeocodingRequest.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "OsmNominatimRunner") );

    // @todo FIXME Must currently be done in the main thread, see bug 257376
    QTimer::singleShot( 0, this, SLOT( startReverseGeocoding() ) );
}

void OsmNominatimRunner::startSearch()
{
    QNetworkReply *reply = m_manager->get(m_searchRequest);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(returnNoResults()));
}

void OsmNominatimRunner::startReverseGeocoding()
{
    QNetworkReply *reply = m_manager->get( m_reverseGeocodingRequest );
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(returnNoReverseGeocodingResult()));
}

void OsmNominatimRunner::handleResult( QNetworkReply* reply )
{
    bool const isSearch = reply->url().path().endsWith( "search" );
    if ( isSearch ) {
        handleSearchResult( reply );
    } else {
        handleReverseGeocodingResult( reply );
    }
}

void OsmNominatimRunner::handleSearchResult( QNetworkReply* reply )
{
    QDomDocument xml;
    if (!xml.setContent(reply->readAll())) {
        qWarning() << "Cannot parse osm nominatim result";
        returnNoResults();
        return;
    }

    QVector<GeoDataPlacemark*> placemarks;
    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName("place");
    for (int i=0; i<places.size(); ++i) {
        QDomNode place = places.at(i);
        QDomNamedNodeMap attributes = place.attributes();
        QString lon = attributes.namedItem("lon").nodeValue();
        QString lat = attributes.namedItem("lat").nodeValue();
        QString desc = attributes.namedItem("display_name").nodeValue();
        QString key = attributes.namedItem("class").nodeValue();
        QString value = attributes.namedItem("type").nodeValue();

        QString name = place.firstChildElement(value).text();
        QString road = place.firstChildElement("road").text();

        QString city = place.firstChildElement("city").text();
        if( city.isEmpty() ) {
            city = place.firstChildElement("town").text();
            if( city.isEmpty() ) {
                city = place.firstChildElement("village").text();
            } if( city.isEmpty() ) {
                city = place.firstChildElement("hamlet").text();
            }
        }

        QString administrative = place.firstChildElement("county").text();
        if( administrative.isEmpty() ) {
            administrative = place.firstChildElement("region").text();
            if( administrative.isEmpty() ) {
                administrative = place.firstChildElement("state").text();
            }
        }

        QString country = place.firstChildElement("country").text();
        qDebug() << "place " << name << ", " << road << ", " << city << ", " << administrative << ", " << country;

        QString description;
        for (int i=0; i<place.childNodes().size(); ++i) {
            QDomElement item = place.childNodes().at(i).toElement();
            description += item.nodeName() + ": " + item.text() + "\n";
        }
        description += "Category: " + key + "/" + value;

        if (!lon.isEmpty() && !lat.isEmpty() && !desc.isEmpty()) {
            QString placemarkName;
            GeoDataPlacemark* placemark = new GeoDataPlacemark;
            // try to provide 2 fields
            if (!name.isEmpty()) {
                placemarkName = name;
            }
            if (!road.isEmpty() && road != placemarkName ) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += road;
            }
            if (!city.isEmpty() && !placemarkName.contains(",") && city != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += city;
            }
            if (!administrative.isEmpty()&& !placemarkName.contains(",") && administrative != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += administrative;
            }
            if (!country.isEmpty()&& !placemarkName.contains(",") && country != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += country;
            }
            if (placemarkName.isEmpty()) {
                placemarkName = desc;
            }
            placemark->setName( placemarkName );
            placemark->setDescription(description);
            placemark->setCoordinate(lon.toDouble(), lat.toDouble(), 0, GeoDataPoint::Degree );
            GeoDataFeature::GeoDataVisualCategory category = GeoDataFeature::OsmVisualCategory( key + "=" + value );
            placemark->setVisualCategory( category );
            placemarks << placemark;
        }
    }

    emit searchFinished( placemarks );
}

void OsmNominatimRunner::handleReverseGeocodingResult( QNetworkReply* reply )
{
    if ( !reply->bytesAvailable() ) {
        returnNoReverseGeocodingResult();
        return;
    }

    QDomDocument xml;
    if ( !xml.setContent( reply->readAll() ) ) {
        mDebug() << "Cannot parse osm nominatim result " << xml.toString();
        returnNoReverseGeocodingResult();
        return;
    }

    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName( "result" );
    if ( places.size() == 1 ) {
        QString address = places.item( 0 ).toElement().text();
        GeoDataPlacemark placemark;
        placemark.setAddress( address );
        placemark.setCoordinate( GeoDataPoint( m_coordinates ) );

        QDomNodeList details = root.elementsByTagName( "addressparts" );
        if ( details.size() == 1 ) {
            GeoDataExtendedData extendedData;
            addData( details, "road", &extendedData );
            addData( details, "house_number", &extendedData );
            addData( details, "village", &extendedData );
            addData( details, "city", &extendedData );
            addData( details, "county", &extendedData );
            addData( details, "state", &extendedData );
            addData( details, "postcode", &extendedData );
            addData( details, "country", &extendedData );
            placemark.setExtendedData( extendedData );
        }

        emit reverseGeocodingFinished( m_coordinates, placemark );
    } else {
        returnNoReverseGeocodingResult();
    }
}

void OsmNominatimRunner::addData( const QDomNodeList &node, const QString &key, GeoDataExtendedData *extendedData )
{
    QDomNodeList child = node.item( 0 ).toElement().elementsByTagName( key );
    if ( child.size() > 0 ) {
        QString text = child.item( 0 ).toElement().text();
        extendedData->addValue( GeoDataData( key, text ) );
    }
}

} // namespace Marble

#include "OsmNominatimRunner.moc"
<commit_msg>OsmNominatim: quieter<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2010      Dennis Nienhüser <earthwings@gentoo.org>
//

#include "OsmNominatimRunner.h"

#include "MarbleAbstractRunner.h"
#include "MarbleDebug.h"
#include "MarbleLocale.h"
#include "GeoDataDocument.h"
#include "GeoDataPlacemark.h"
#include "GeoDataExtendedData.h"
#include "TinyWebBrowser.h"

#include <QtCore/QString>
#include <QtCore/QVector>
#include <QtCore/QUrl>
#include <QtCore/QTimer>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtXml/QDomDocument>

namespace Marble
{

OsmNominatimRunner::OsmNominatimRunner( QObject *parent ) :
    MarbleAbstractRunner( parent ), m_manager( new QNetworkAccessManager (this ) )
{
    connect(m_manager, SIGNAL(finished(QNetworkReply*)),
            this, SLOT(handleResult(QNetworkReply*)));
}

OsmNominatimRunner::~OsmNominatimRunner()
{
    // nothing to do
}

GeoDataFeature::GeoDataVisualCategory OsmNominatimRunner::category() const
{
    return GeoDataFeature::OsmSite;
}

void OsmNominatimRunner::returnNoResults()
{
    emit searchFinished( QVector<GeoDataPlacemark*>() );
}

void OsmNominatimRunner::returnNoReverseGeocodingResult()
{
    emit reverseGeocodingFinished( m_coordinates, GeoDataPlacemark() );
}

void OsmNominatimRunner::search( const QString &searchTerm )
{
    QString base = "http://nominatim.openstreetmap.org/search?";
    QString query = "q=%1&format=xml&addressdetails=1&accept-language=%2";
    QString url = QString(base + query).arg(searchTerm).arg(MarbleLocale::languageCode());

    m_searchRequest.setUrl(QUrl(url));
    m_searchRequest.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "OsmNominatimRunner") );

    // @todo FIXME Must currently be done in the main thread, see bug 257376
    QTimer::singleShot( 0, this, SLOT( startSearch() ) );
}

void OsmNominatimRunner::reverseGeocoding( const GeoDataCoordinates &coordinates )
{
    m_coordinates = coordinates;
    QString base = "http://nominatim.openstreetmap.org/reverse?format=xml&addressdetails=1";
    // @todo: Alternative URI with addressdetails=1 could be used for shorther placemark name
    QString query = "&lon=%1&lat=%2&accept-language=%3";
    double lon = coordinates.longitude( GeoDataCoordinates::Degree );
    double lat = coordinates.latitude( GeoDataCoordinates::Degree );
    QString url = QString( base + query ).arg( lon ).arg( lat ).arg( MarbleLocale::languageCode() );

    m_reverseGeocodingRequest.setUrl(QUrl(url));
    m_reverseGeocodingRequest.setRawHeader("User-Agent", TinyWebBrowser::userAgent("Browser", "OsmNominatimRunner") );

    // @todo FIXME Must currently be done in the main thread, see bug 257376
    QTimer::singleShot( 0, this, SLOT( startReverseGeocoding() ) );
}

void OsmNominatimRunner::startSearch()
{
    QNetworkReply *reply = m_manager->get(m_searchRequest);
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(returnNoResults()));
}

void OsmNominatimRunner::startReverseGeocoding()
{
    QNetworkReply *reply = m_manager->get( m_reverseGeocodingRequest );
    connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
            this, SLOT(returnNoReverseGeocodingResult()));
}

void OsmNominatimRunner::handleResult( QNetworkReply* reply )
{
    bool const isSearch = reply->url().path().endsWith( "search" );
    if ( isSearch ) {
        handleSearchResult( reply );
    } else {
        handleReverseGeocodingResult( reply );
    }
}

void OsmNominatimRunner::handleSearchResult( QNetworkReply* reply )
{
    QDomDocument xml;
    if (!xml.setContent(reply->readAll())) {
        qWarning() << "Cannot parse osm nominatim result";
        returnNoResults();
        return;
    }

    QVector<GeoDataPlacemark*> placemarks;
    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName("place");
    for (int i=0; i<places.size(); ++i) {
        QDomNode place = places.at(i);
        QDomNamedNodeMap attributes = place.attributes();
        QString lon = attributes.namedItem("lon").nodeValue();
        QString lat = attributes.namedItem("lat").nodeValue();
        QString desc = attributes.namedItem("display_name").nodeValue();
        QString key = attributes.namedItem("class").nodeValue();
        QString value = attributes.namedItem("type").nodeValue();

        QString name = place.firstChildElement(value).text();
        QString road = place.firstChildElement("road").text();

        QString city = place.firstChildElement("city").text();
        if( city.isEmpty() ) {
            city = place.firstChildElement("town").text();
            if( city.isEmpty() ) {
                city = place.firstChildElement("village").text();
            } if( city.isEmpty() ) {
                city = place.firstChildElement("hamlet").text();
            }
        }

        QString administrative = place.firstChildElement("county").text();
        if( administrative.isEmpty() ) {
            administrative = place.firstChildElement("region").text();
            if( administrative.isEmpty() ) {
                administrative = place.firstChildElement("state").text();
            }
        }

        QString country = place.firstChildElement("country").text();

        QString description;
        for (int i=0; i<place.childNodes().size(); ++i) {
            QDomElement item = place.childNodes().at(i).toElement();
            description += item.nodeName() + ": " + item.text() + "\n";
        }
        description += "Category: " + key + "/" + value;

        if (!lon.isEmpty() && !lat.isEmpty() && !desc.isEmpty()) {
            QString placemarkName;
            GeoDataPlacemark* placemark = new GeoDataPlacemark;
            // try to provide 2 fields
            if (!name.isEmpty()) {
                placemarkName = name;
            }
            if (!road.isEmpty() && road != placemarkName ) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += road;
            }
            if (!city.isEmpty() && !placemarkName.contains(",") && city != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += city;
            }
            if (!administrative.isEmpty()&& !placemarkName.contains(",") && administrative != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += administrative;
            }
            if (!country.isEmpty()&& !placemarkName.contains(",") && country != placemarkName) {
                if( !placemarkName.isEmpty() ) {
                    placemarkName += ", ";
                }
                placemarkName += country;
            }
            if (placemarkName.isEmpty()) {
                placemarkName = desc;
            }
            placemark->setName( placemarkName );
            placemark->setDescription(description);
            placemark->setCoordinate(lon.toDouble(), lat.toDouble(), 0, GeoDataPoint::Degree );
            GeoDataFeature::GeoDataVisualCategory category = GeoDataFeature::OsmVisualCategory( key + "=" + value );
            placemark->setVisualCategory( category );
            placemarks << placemark;
        }
    }

    emit searchFinished( placemarks );
}

void OsmNominatimRunner::handleReverseGeocodingResult( QNetworkReply* reply )
{
    if ( !reply->bytesAvailable() ) {
        returnNoReverseGeocodingResult();
        return;
    }

    QDomDocument xml;
    if ( !xml.setContent( reply->readAll() ) ) {
        mDebug() << "Cannot parse osm nominatim result " << xml.toString();
        returnNoReverseGeocodingResult();
        return;
    }

    QDomElement root = xml.documentElement();
    QDomNodeList places = root.elementsByTagName( "result" );
    if ( places.size() == 1 ) {
        QString address = places.item( 0 ).toElement().text();
        GeoDataPlacemark placemark;
        placemark.setAddress( address );
        placemark.setCoordinate( GeoDataPoint( m_coordinates ) );

        QDomNodeList details = root.elementsByTagName( "addressparts" );
        if ( details.size() == 1 ) {
            GeoDataExtendedData extendedData;
            addData( details, "road", &extendedData );
            addData( details, "house_number", &extendedData );
            addData( details, "village", &extendedData );
            addData( details, "city", &extendedData );
            addData( details, "county", &extendedData );
            addData( details, "state", &extendedData );
            addData( details, "postcode", &extendedData );
            addData( details, "country", &extendedData );
            placemark.setExtendedData( extendedData );
        }

        emit reverseGeocodingFinished( m_coordinates, placemark );
    } else {
        returnNoReverseGeocodingResult();
    }
}

void OsmNominatimRunner::addData( const QDomNodeList &node, const QString &key, GeoDataExtendedData *extendedData )
{
    QDomNodeList child = node.item( 0 ).toElement().elementsByTagName( key );
    if ( child.size() > 0 ) {
        QString text = child.item( 0 ).toElement().text();
        extendedData->addValue( GeoDataData( key, text ) );
    }
}

} // namespace Marble

#include "OsmNominatimRunner.moc"
<|endoftext|>


<commit_before>
#include <algorithm>
#include <vector>

#include "astronomy/frames.hpp"
#include "geometry/interval.hpp"
#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/methods.hpp"
#include "integrators/symmetric_linear_multistep_integrator.hpp"
#include "mathematica/mathematica.hpp"
#include "numerics/apodization.hpp"
#include "numerics/fast_fourier_transform.hpp"
#include "numerics/frequency_analysis.hpp"
#include "numerics/poisson_series.hpp"
#include "numerics/polynomial_evaluators.hpp"
#include "physics/ephemeris.hpp"
#include "physics/solar_system.hpp"
#include "quantities/astronomy.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/approximate_quantity.hpp"

namespace principia {
namespace physics {

using astronomy::ICRS;
using geometry::Displacement;
using geometry::Instant;
using geometry::Interval;
using geometry::Position;
using integrators::SymmetricLinearMultistepIntegrator;
using integrators::methods::QuinlanTremaine1990Order12;
using numerics::EstrinEvaluator;
using numerics::FastFourierTransform;
using numerics::PoissonSeries;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Length;
using quantities::Time;
using quantities::astronomy::JulianYear;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Radian;
using quantities::si::Second;

namespace apodization = numerics::apodization;
namespace frequency_analysis = numerics::frequency_analysis;

static constexpr int approximation_degree = 5;
static constexpr int log2_number_of_samples = 10;
static constexpr int number_of_frequencies = 10;

class AnalyticalSeriesTest : public ::testing::Test {
 protected:
  AnalyticalSeriesTest()
      : logger_(TEMP_DIR / "analytical_series.wl",
               /*make_unique=*/false) {
    google::LogToStderr();
  }

  template<int degree>
  PoissonSeries<Displacement<ICRS>, approximation_degree, EstrinEvaluator>
  ComputeCompactRepresentation(ContinuousTrajectory<ICRS> const& trajectory) {
    Instant const t_min = trajectory.t_min();
    Instant const t_max = trajectory.t_max();
    auto const piecewise_poisson_series =
        trajectory.ToPiecewisePoissonSeries<degree>(t_min, t_max);

    int step = 0;

    auto angular_frequency_calculator =
        [this, &step, t_min, t_max](
            auto const& residual) -> std::optional<AngularFrequency> {
      Time const Δt = (t_max - t_min) / (1 << log2_number_of_samples);
      LOG(INFO) << "step=" << step;
      if (step == 0) {
        ++step;
        return AngularFrequency();
      } else if (step <= number_of_frequencies) {
        ++step;
        Length max_residual;
        std::vector<Displacement<ICRS>> residuals;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          residuals.push_back(residual(t_min + i * Δt));
          max_residual = std::max(max_residual, residuals.back().Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual;
        auto fft =
            std::make_unique<FastFourierTransform<Displacement<ICRS>,
                                                  1 << log2_number_of_samples>>(
                residuals, Δt);
        auto const mode = fft->Mode();
        Interval<Time> const period{2 * π * Radian / mode.max,
                                    2 * π * Radian / mode.min};
        LOG(INFO) << "period=" << period;
        auto const precise_mode = frequency_analysis::PreciseMode(
            mode, residual, apodization::Hann<EstrinEvaluator>(t_min, t_max));
        auto const precise_period = 2 * π * Radian / precise_mode;
        LOG(INFO) << "precise_period=" << precise_period;
        logger_.Append(
            "precisePeriods", precise_period, mathematica::ExpressIn(Second));
        return precise_mode;
      } else {
        Length max_residual;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          max_residual =
              std::max(max_residual, residual(t_min + i * Δt).Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual;
        return std::nullopt;
      }
    };

    return frequency_analysis::IncrementalProjection<approximation_degree>(
        piecewise_poisson_series,
        angular_frequency_calculator,
        apodization::Dirichlet<EstrinEvaluator>(t_min, t_max),
        t_min,
        t_max);
  }

  mathematica::Logger logger_;
};

#define PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(                   \
    degree, approximation, trajectory)                                   \
  case degree: {                                                         \
    approximation = std::make_unique<PoissonSeries<Displacement<ICRS>,   \
                                                   approximation_degree, \
                                                   EstrinEvaluator>>(    \
        ComputeCompactRepresentation<(degree)>(trajectory));             \
    break;                                                               \
  }

#if !_DEBUG
TEST_F(AnalyticalSeriesTest, CompactRepresentation) {
  SolarSystem<ICRS> solar_system_at_j2000(
      SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
      SOLUTION_DIR / "astronomy" /
          "sol_initial_state_jd_2451545_000000000.proto.txt");

  // NOTE(phl): Keep these parameters aligned with
  // sol_numerics_blueprint.proto.txt.
  auto const ephemeris = solar_system_at_j2000.MakeEphemeris(
      /*accuracy_parameters=*/{/*fitting_tolerance=*/1 * Milli(Metre),
                               /*geopotential_tolerance=*/0x1p-24},
      Ephemeris<ICRS>::FixedStepParameters(
          SymmetricLinearMultistepIntegrator<QuinlanTremaine1990Order12,
                                             Position<ICRS>>(),
          /*step=*/10 * Minute));
  ephemeris->Prolong(solar_system_at_j2000.epoch() + 0.25 * JulianYear);

  auto const& io_trajectory =
      solar_system_at_j2000.trajectory(*ephemeris, "Io");
  int const io_piecewise_poisson_series_degree =
      io_trajectory.PiecewisePoissonSeriesDegree(io_trajectory.t_min(),
                                                 io_trajectory.t_max());
  std::unique_ptr<
      PoissonSeries<Displacement<ICRS>, approximation_degree, EstrinEvaluator>>
      io_approximation;

  switch (io_piecewise_poisson_series_degree) {
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        3, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        4, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        5, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        6, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        7, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        8, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        9, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        10, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        11, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        12, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        13, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        14, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        15, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        16, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        17, io_approximation, io_trajectory);
    default:
      LOG(FATAL) << "Unexpected degree " << io_piecewise_poisson_series_degree;
  };

  logger_.Set("approximation",
              *io_approximation,
              mathematica::ExpressIn(Metre, Second, Radian));
}
#endif

#undef PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE

}  // namespace physics
}  // namespace principia
<commit_msg>A small trace.<commit_after>
#include <algorithm>
#include <vector>

#include "astronomy/frames.hpp"
#include "geometry/interval.hpp"
#include "geometry/named_quantities.hpp"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/methods.hpp"
#include "integrators/symmetric_linear_multistep_integrator.hpp"
#include "mathematica/mathematica.hpp"
#include "numerics/apodization.hpp"
#include "numerics/fast_fourier_transform.hpp"
#include "numerics/frequency_analysis.hpp"
#include "numerics/poisson_series.hpp"
#include "numerics/polynomial_evaluators.hpp"
#include "physics/ephemeris.hpp"
#include "physics/solar_system.hpp"
#include "quantities/astronomy.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/approximate_quantity.hpp"

namespace principia {
namespace physics {

using astronomy::ICRS;
using geometry::Displacement;
using geometry::Instant;
using geometry::Interval;
using geometry::Position;
using integrators::SymmetricLinearMultistepIntegrator;
using integrators::methods::QuinlanTremaine1990Order12;
using numerics::EstrinEvaluator;
using numerics::FastFourierTransform;
using numerics::PoissonSeries;
using quantities::Angle;
using quantities::AngularFrequency;
using quantities::Length;
using quantities::Time;
using quantities::astronomy::JulianYear;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Radian;
using quantities::si::Second;

namespace apodization = numerics::apodization;
namespace frequency_analysis = numerics::frequency_analysis;

static constexpr int approximation_degree = 5;
static constexpr int log2_number_of_samples = 10;
static constexpr int number_of_frequencies = 10;

class AnalyticalSeriesTest : public ::testing::Test {
 protected:
  AnalyticalSeriesTest()
      : logger_(TEMP_DIR / "analytical_series.wl",
               /*make_unique=*/false) {
    google::LogToStderr();
  }

  template<int degree>
  PoissonSeries<Displacement<ICRS>, approximation_degree, EstrinEvaluator>
  ComputeCompactRepresentation(ContinuousTrajectory<ICRS> const& trajectory) {
    Instant const t_min = trajectory.t_min();
    Instant const t_max = trajectory.t_max();
    auto const piecewise_poisson_series =
        trajectory.ToPiecewisePoissonSeries<degree>(t_min, t_max);

    logger_.Set("tMin", t_min, mathematica::ExpressIn(Second));
    logger_.Set("tMax", t_max, mathematica::ExpressIn(Second));

    int step = 0;

    auto angular_frequency_calculator =
        [this, &step, t_min, t_max](
            auto const& residual) -> std::optional<AngularFrequency> {
      Time const Δt = (t_max - t_min) / (1 << log2_number_of_samples);
      LOG(INFO) << "step=" << step;
      if (step == 0) {
        ++step;
        return AngularFrequency();
      } else if (step <= number_of_frequencies) {
        ++step;
        Length max_residual;
        std::vector<Displacement<ICRS>> residuals;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          residuals.push_back(residual(t_min + i * Δt));
          max_residual = std::max(max_residual, residuals.back().Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual;
        auto fft =
            std::make_unique<FastFourierTransform<Displacement<ICRS>,
                                                  1 << log2_number_of_samples>>(
                residuals, Δt);
        auto const mode = fft->Mode();
        Interval<Time> const period{2 * π * Radian / mode.max,
                                    2 * π * Radian / mode.min};
        LOG(INFO) << "period=" << period;
        auto const precise_mode = frequency_analysis::PreciseMode(
            mode, residual, apodization::Hann<EstrinEvaluator>(t_min, t_max));
        auto const precise_period = 2 * π * Radian / precise_mode;
        LOG(INFO) << "precise_period=" << precise_period;
        logger_.Append(
            "precisePeriods", precise_period, mathematica::ExpressIn(Second));
        return precise_mode;
      } else {
        Length max_residual;
        for (int i = 0; i < 1 << log2_number_of_samples; ++i) {
          max_residual =
              std::max(max_residual, residual(t_min + i * Δt).Norm());
        }
        LOG(INFO) << "max_residual=" << max_residual;
        return std::nullopt;
      }
    };

    return frequency_analysis::IncrementalProjection<approximation_degree>(
        piecewise_poisson_series,
        angular_frequency_calculator,
        apodization::Dirichlet<EstrinEvaluator>(t_min, t_max),
        t_min,
        t_max);
  }

  mathematica::Logger logger_;
};

#define PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(                   \
    degree, approximation, trajectory)                                   \
  case degree: {                                                         \
    approximation = std::make_unique<PoissonSeries<Displacement<ICRS>,   \
                                                   approximation_degree, \
                                                   EstrinEvaluator>>(    \
        ComputeCompactRepresentation<(degree)>(trajectory));             \
    break;                                                               \
  }

#if !_DEBUG
TEST_F(AnalyticalSeriesTest, CompactRepresentation) {
  SolarSystem<ICRS> solar_system_at_j2000(
      SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
      SOLUTION_DIR / "astronomy" /
          "sol_initial_state_jd_2451545_000000000.proto.txt");

  // NOTE(phl): Keep these parameters aligned with
  // sol_numerics_blueprint.proto.txt.
  auto const ephemeris = solar_system_at_j2000.MakeEphemeris(
      /*accuracy_parameters=*/{/*fitting_tolerance=*/1 * Milli(Metre),
                               /*geopotential_tolerance=*/0x1p-24},
      Ephemeris<ICRS>::FixedStepParameters(
          SymmetricLinearMultistepIntegrator<QuinlanTremaine1990Order12,
                                             Position<ICRS>>(),
          /*step=*/10 * Minute));
  ephemeris->Prolong(solar_system_at_j2000.epoch() + 0.25 * JulianYear);

  auto const& io_trajectory =
      solar_system_at_j2000.trajectory(*ephemeris, "Moon");
  int const io_piecewise_poisson_series_degree =
      io_trajectory.PiecewisePoissonSeriesDegree(io_trajectory.t_min(),
                                                 io_trajectory.t_max());
  std::unique_ptr<
      PoissonSeries<Displacement<ICRS>, approximation_degree, EstrinEvaluator>>
      io_approximation;

  switch (io_piecewise_poisson_series_degree) {
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        3, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        4, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        5, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        6, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        7, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        8, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        9, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        10, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        11, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        12, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        13, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        14, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        15, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        16, io_approximation, io_trajectory);
    PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE(
        17, io_approximation, io_trajectory);
    default:
      LOG(FATAL) << "Unexpected degree " << io_piecewise_poisson_series_degree;
  };

  logger_.Set("approximation",
              *io_approximation,
              mathematica::ExpressIn(Metre, Second, Radian));
}
#endif

#undef PRINCIPIA_COMPUTE_COMPACT_REPRESENTATION_CASE

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include "photoeffects.hpp"

using namespace cv;

TEST(photoeffects, SepiaFakeTest) {
    Mat src(10, 10, CV_8UC1), dst;

    EXPECT_EQ(0, sepia(src, dst));
}

TEST(photoeffects, SepiaFailTest) {
    Mat src(10, 10, CV_8UC3), dst;

    EXPECT_EQ(1, sepia(src, dst));
}

TEST(photoeffects, SepiaTest) {
    Mat src(10, 10, CV_8UC1), dst, hsvDst;
    vector<Mat> channels(3);

    EXPECT_EQ(0, sepia(src, dst));
    cvtColor(dst, hsvDst, CV_BGR2HSV);
    split(hsvDst, channels);
    EXPECT_LE(19 - 1, channels[0].at<uchar>(0, 0)); // hue = 19
    EXPECT_GE(19 + 1, channels[0].at<uchar>(0, 0));
    EXPECT_LE(78 - 1, channels[1].at<uchar>(0, 0)); // saturation = 78
    EXPECT_GE(78 + 1, channels[1].at<uchar>(0, 0));
    EXPECT_LE(src.at<uchar>(0, 0) + 20 - 1, channels[2].at<uchar>(0, 0));
    EXPECT_GE(src.at<uchar>(0, 0) + 20 + 1, channels[2].at<uchar>(0, 0));
}

<commit_msg>Matrix initialization in the test for sepia effect.<commit_after>#include <gtest/gtest.h>

#include "photoeffects.hpp"

using namespace cv;

TEST(photoeffects, SepiaFakeTest) {
    Mat src(10, 10, CV_8UC1), dst;

    EXPECT_EQ(0, sepia(src, dst));
}

TEST(photoeffects, SepiaFailTest) {
    Mat src(10, 10, CV_8UC3), dst;

    EXPECT_EQ(1, sepia(src, dst));
}

TEST(photoeffects, SepiaTest) {
    Mat src(10, 10, CV_8UC1, Scalar(0)), dst, hsvDst;
    vector<Mat> channels(3);

    EXPECT_EQ(0, sepia(src, dst));
    cvtColor(dst, hsvDst, CV_BGR2HSV);
    split(hsvDst, channels);
    EXPECT_LE(19 - 1, channels[0].at<uchar>(0, 0)); // hue = 19
    EXPECT_GE(19 + 1, channels[0].at<uchar>(0, 0));
    EXPECT_LE(78 - 1, channels[1].at<uchar>(0, 0)); // saturation = 78
    EXPECT_GE(78 + 1, channels[1].at<uchar>(0, 0));
    EXPECT_LE(src.at<uchar>(0, 0) + 20 - 1, channels[2].at<uchar>(0, 0));
    EXPECT_GE(src.at<uchar>(0, 0) + 20 + 1, channels[2].at<uchar>(0, 0));
}

<|endoftext|>


<commit_before>/**
 *  Copyright (C) 2015 Topology LP
 *
 *  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.
 */

#include <bonefish/websocket/websocket_transport.hpp>
#include <bonefish/messages/wamp_message.hpp>
#include <bonefish/messages/wamp_message_type.hpp>
#include <bonefish/serialization/expandable_buffer.hpp>
#include <bonefish/serialization/wamp_serializer.hpp>
#include <bonefish/trace/trace.hpp>

#include <iostream>

namespace bonefish {

websocket_transport::websocket_transport(const std::shared_ptr<wamp_serializer>& serializer,
        const websocketpp::connection_hdl& handle,
        const std::shared_ptr<websocketpp::server<websocket_config>>& server)
    : m_serializer(serializer)
    , m_handle(handle)
    , m_server(server)
{
}

bool websocket_transport::send_message(const wamp_message* message)
{
    BONEFISH_TRACE("sending message: %1%", message_type_to_string(message->get_type()));
    expandable_buffer buffer = m_serializer->serialize(message);
    m_server->send(m_handle, buffer.data(), buffer.size(), websocketpp::frame::opcode::BINARY);

    return true;
}

} // namespace bonefish
<commit_msg>[websocket] Send JSON as text rather than binary.<commit_after>/**
 *  Copyright (C) 2015 Topology LP
 *
 *  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.
 */

#include <bonefish/websocket/websocket_transport.hpp>
#include <bonefish/messages/wamp_message.hpp>
#include <bonefish/messages/wamp_message_type.hpp>
#include <bonefish/serialization/expandable_buffer.hpp>
#include <bonefish/serialization/wamp_serializer.hpp>
#include <bonefish/trace/trace.hpp>

#include <iostream>

namespace bonefish {

websocket_transport::websocket_transport(const std::shared_ptr<wamp_serializer>& serializer,
        const websocketpp::connection_hdl& handle,
        const std::shared_ptr<websocketpp::server<websocket_config>>& server)
    : m_serializer(serializer)
    , m_handle(handle)
    , m_server(server)
{
}

bool websocket_transport::send_message(const wamp_message* message)
{
    BONEFISH_TRACE("sending message: %1%", message_type_to_string(message->get_type()));
    expandable_buffer buffer = m_serializer->serialize(message);
    auto opcode = (m_serializer->get_type() == wamp_serializer_type::JSON)
            ? websocketpp::frame::opcode::TEXT
            : websocketpp::frame::opcode::BINARY;
    m_server->send(m_handle, buffer.data(), buffer.size(), opcode);

    return true;
}

} // namespace bonefish
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://www.opensource.org/licenses/MIT)
//=======================================================================

#ifndef TYPE_TRAITS_H
#define TYPE_TRAITS_H

#include <types.hpp>
#include <enable_if.hpp>

namespace std {

template <typename T>
struct iterator_traits {
    using value_type      = typename T::value_type; ///< The value type of the iterator
    using reference       = typename T::reference; ///< The reference type of the iterator
    using pointer         = typename T::pointer; ///< The pointer type of the iterator
    using difference_type = typename T::difference_type; ///< The difference type of the iterator
};

template <typename T>
struct iterator_traits <T*> {
    using value_type      = T; ///< The value type of the iterator
    using reference       = T&; ///< The reference type of the iterator
    using pointer         = T*; ///< The pointer type of the iterator
    using difference_type = size_t; ///< The difference type of the iterator
};

/* remove_reference */

template<typename T>
struct remove_reference {
    using type = T;
};

template<typename T>
struct remove_reference<T&>{
    using type = T;
};

template<typename T>
struct remove_reference<T&&> {
    using type = T;
};

template<typename T>
using remove_reference_t = typename remove_reference<T>::type;

/* remove_extent */

template<typename T>
struct remove_extent {
    using type = T;
};

template<typename T>
struct remove_extent<T[]> {
    using type = T;
};

template<typename T, size_t N>
struct remove_extent<T[N]> {
    using type = T;
};

template<typename T>
using remove_extent_t = typename remove_extent<T>::type;

/* remove_const */

template<typename T>
struct remove_const {
    using type = T;
};

template<typename T>
struct remove_const<const T> {
    using type = T;
};

template<typename T>
using remove_const_t = typename remove_const<T>::type;

/* add_const */

template<typename T>
struct add_const {
    using type = const T;
};

template<typename T>
struct add_const<const T> {
    using type = T;
};

template<typename T>
using add_const_t = typename add_const<T>::type;

/* remove_volatile */

template<typename T>
struct remove_volatile {
    using type = T;
};

template<typename T>
struct remove_volatile<volatile T> {
    using type = T;
};

template<typename T>
using remove_volatile_t = typename remove_volatile<T>::type;

/* remove_cv */

template<typename T>
struct remove_cv {
    using type = typename std::remove_volatile<typename std::remove_const<T>::type>::type;
};

template<typename T>
using remove_cv_t = typename remove_cv<T>::type;

/* conditional */

template<bool B, typename T, typename F>
struct conditional {
    using type = T;
};

template<typename T, typename F>
struct conditional<false, T, F> {
    using type = F;
};

template<bool B, typename T, typename F>
using conditional_t = typename std::conditional<B, T, F>::type;

/* is_trivially_destructible */

template<typename T>
struct is_trivially_destructible {
    static constexpr const bool value = __has_trivial_destructor(T);
};

template<>
struct is_trivially_destructible<void> {
    static constexpr const bool value = true;
};

/* is_trivially_destructible */

template<typename T>
struct has_trivial_assign {
    static constexpr const bool value = __has_trivial_assign(T);
};

/* is_pointer */

/*!
 * \brief Traits to test if given type is a pointer type
 */
template <typename T>
struct is_pointer {
    static constexpr const bool value = false;
};

/*!
 * \copdoc is_pointer
 */
template <typename T>
struct is_pointer<T*>{
    static constexpr const bool value = true;
};

/* is_reference */

/*!
 * \brief Traits to test if given type is a reference type
 */
template <typename T>
struct is_reference {
    static constexpr const bool value = false;
};

/*!
 * \copdoc is_reference
 */
template <typename T>
struct is_reference<T&>{
    static constexpr const bool value = true;
};

/*!
 * \copdoc is_reference
 */
template <typename T>
struct is_reference<T&&>{
    static constexpr const bool value = true;
};

/* is_array */

/*!
 * \brief Traits to test if given type is an array type
 */
template<typename T>
struct is_array {
    static constexpr const bool value = false;
};

/*!
 * \copdoc is_array
 */
template<typename T>
struct is_array<T[]>{
    static constexpr const bool value = true;
};

/*!
 * \copdoc is_array
 */
template<typename T, size_t N>
struct is_array<T[N]>{
    static constexpr const bool value = true;
};

/* is_function */

template<typename T>
struct is_function {
    static constexpr const bool value = false;
};

template<typename Ret, typename... Args>
struct is_function<Ret(Args...)> {
    static constexpr const bool value = true;
};

template<typename Ret, typename... Args>
struct is_function<Ret(Args......)> {
    static constexpr const bool value = true;
};

/* add_rvalue_reference */

template<typename T, typename Enable = void>
struct add_rvalue_reference;

template<typename T>
struct add_rvalue_reference<T, typename std::enable_if_t<std::is_reference<T>::value>> {
    using type = T;
};

template<typename T>
struct add_rvalue_reference<T, typename std::disable_if_t<!std::is_reference<T>::value>> {
    using type = T&&;
};

/* add_pointer */

template<typename T>
struct add_pointer {
    using type = typename std::remove_reference<T>::type*;
};

template<typename T>
using add_pointer_t = typename add_pointer<T>::type;

/* decay */

template<typename T>
struct decay {
    using U    = std::remove_reference_t<T>;
    using type = std::conditional_t<
        std::is_array<U>::value,
        std::remove_extent_t<U>*,
        std::conditional_t<
            std::is_function<U>::value,
            std::add_pointer_t<U>,
            std::remove_cv_t<U>>>;
};

/* is_same */

/*!
 * \brief Traits to test if two types are the same
 */
template<typename T1, typename T2>
struct is_same {
    static constexpr const bool value = false;
};

/*!
 * \copydoc is_same
 */
template<typename T1>
struct is_same <T1, T1> {
    static constexpr const bool value = true;
};

} //end of namespace std

#endif
<commit_msg>is_integral traits<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://www.opensource.org/licenses/MIT)
//=======================================================================

#ifndef TYPE_TRAITS_H
#define TYPE_TRAITS_H

#include <types.hpp>
#include <enable_if.hpp>

namespace std {

template <typename T>
struct iterator_traits {
    using value_type      = typename T::value_type; ///< The value type of the iterator
    using reference       = typename T::reference; ///< The reference type of the iterator
    using pointer         = typename T::pointer; ///< The pointer type of the iterator
    using difference_type = typename T::difference_type; ///< The difference type of the iterator
};

template <typename T>
struct iterator_traits <T*> {
    using value_type      = T; ///< The value type of the iterator
    using reference       = T&; ///< The reference type of the iterator
    using pointer         = T*; ///< The pointer type of the iterator
    using difference_type = size_t; ///< The difference type of the iterator
};

/* remove_reference */

template<typename T>
struct remove_reference {
    using type = T;
};

template<typename T>
struct remove_reference<T&>{
    using type = T;
};

template<typename T>
struct remove_reference<T&&> {
    using type = T;
};

template<typename T>
using remove_reference_t = typename remove_reference<T>::type;

/* remove_extent */

template<typename T>
struct remove_extent {
    using type = T;
};

template<typename T>
struct remove_extent<T[]> {
    using type = T;
};

template<typename T, size_t N>
struct remove_extent<T[N]> {
    using type = T;
};

template<typename T>
using remove_extent_t = typename remove_extent<T>::type;

/* remove_const */

template<typename T>
struct remove_const {
    using type = T;
};

template<typename T>
struct remove_const<const T> {
    using type = T;
};

template<typename T>
using remove_const_t = typename remove_const<T>::type;

/* add_const */

template<typename T>
struct add_const {
    using type = const T;
};

template<typename T>
struct add_const<const T> {
    using type = T;
};

template<typename T>
using add_const_t = typename add_const<T>::type;

/* remove_volatile */

template<typename T>
struct remove_volatile {
    using type = T;
};

template<typename T>
struct remove_volatile<volatile T> {
    using type = T;
};

template<typename T>
using remove_volatile_t = typename remove_volatile<T>::type;

/* remove_cv */

template<typename T>
struct remove_cv {
    using type = typename std::remove_volatile<typename std::remove_const<T>::type>::type;
};

template<typename T>
using remove_cv_t = typename remove_cv<T>::type;

/* conditional */

template<bool B, typename T, typename F>
struct conditional {
    using type = T;
};

template<typename T, typename F>
struct conditional<false, T, F> {
    using type = F;
};

template<bool B, typename T, typename F>
using conditional_t = typename std::conditional<B, T, F>::type;

/* is_trivially_destructible */

template<typename T>
struct is_trivially_destructible {
    static constexpr const bool value = __has_trivial_destructor(T);
};

template<>
struct is_trivially_destructible<void> {
    static constexpr const bool value = true;
};

/* is_trivially_destructible */

template<typename T>
struct has_trivial_assign {
    static constexpr const bool value = __has_trivial_assign(T);
};

/* is_pointer */

/*!
 * \brief Traits to test if given type is a pointer type
 */
template <typename T>
struct is_pointer {
    static constexpr const bool value = false;
};

/*!
 * \copdoc is_pointer
 */
template <typename T>
struct is_pointer<T*>{
    static constexpr const bool value = true;
};

/* is_reference */

/*!
 * \brief Traits to test if given type is a reference type
 */
template <typename T>
struct is_reference {
    static constexpr const bool value = false;
};

/*!
 * \copdoc is_reference
 */
template <typename T>
struct is_reference<T&>{
    static constexpr const bool value = true;
};

/*!
 * \copdoc is_reference
 */
template <typename T>
struct is_reference<T&&>{
    static constexpr const bool value = true;
};

/* is_array */

/*!
 * \brief Traits to test if given type is an array type
 */
template<typename T>
struct is_array {
    static constexpr const bool value = false;
};

/*!
 * \copdoc is_array
 */
template<typename T>
struct is_array<T[]>{
    static constexpr const bool value = true;
};

/*!
 * \copdoc is_array
 */
template<typename T, size_t N>
struct is_array<T[N]>{
    static constexpr const bool value = true;
};

/* is_function */

template<typename T>
struct is_function {
    static constexpr const bool value = false;
};

template<typename Ret, typename... Args>
struct is_function<Ret(Args...)> {
    static constexpr const bool value = true;
};

template<typename Ret, typename... Args>
struct is_function<Ret(Args......)> {
    static constexpr const bool value = true;
};

/* add_rvalue_reference */

template<typename T, typename Enable = void>
struct add_rvalue_reference;

template<typename T>
struct add_rvalue_reference<T, typename std::enable_if_t<std::is_reference<T>::value>> {
    using type = T;
};

template<typename T>
struct add_rvalue_reference<T, typename std::disable_if_t<!std::is_reference<T>::value>> {
    using type = T&&;
};

/* add_pointer */

template<typename T>
struct add_pointer {
    using type = typename std::remove_reference<T>::type*;
};

template<typename T>
using add_pointer_t = typename add_pointer<T>::type;

/* decay */

template<typename T>
struct decay {
    using U    = std::remove_reference_t<T>;
    using type = std::conditional_t<
        std::is_array<U>::value,
        std::remove_extent_t<U>*,
        std::conditional_t<
            std::is_function<U>::value,
            std::add_pointer_t<U>,
            std::remove_cv_t<U>>>;
};

/* is_same */

/*!
 * \brief Traits to test if two types are the same
 */
template<typename T1, typename T2>
struct is_same {
    static constexpr const bool value = false;
};

/*!
 * \copydoc is_same
 */
template<typename T1>
struct is_same <T1, T1> {
    static constexpr const bool value = true;
};

/* is_integral */

template <typename>
struct is_integral {
    static constexpr const bool value = false;
};

template <typename T>
struct is_integral <const T>{
    static constexpr const bool value = is_integral<T>::value;
};

template <>
struct is_integral <bool> {
    static constexpr const bool value = true;
};

template <>
struct is_integral <char> {
    static constexpr const bool value = true;
};

template <>
struct is_integral <signed char> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<unsigned char> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<short> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<unsigned short> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<int> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<unsigned int> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<long> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<unsigned long> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<long long> {
    static constexpr const bool value = true;
};

template <>
struct is_integral<unsigned long long> {
    static constexpr const bool value = true;
};

} //end of namespace std

#endif
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#include "itkSliceBySliceImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"
#include "itkPipelineMonitorImageFilter.h"
#include "itkTestingMacros.h"
#include "itkMedianImageFilter.h"

void sliceCallBack(itk::Object* object, const itk::EventObject &, void*)
{
  // the same typedefs than in the main function - should be done in a nicer way
  const int                 Dimension = 3;
  typedef unsigned char     PixelType;

  typedef itk::Image< PixelType, Dimension >                   ImageType;
  typedef itk::SliceBySliceImageFilter< ImageType, ImageType > FilterType;
  typedef itk::MedianImageFilter< FilterType::InternalInputImageType,
    FilterType::InternalOutputImageType >                      MedianType;

  // real stuff begins here
  // get the slice by slice filter and the median filter
  FilterType * filter = dynamic_cast< FilterType * >( object );
  MedianType * median = dynamic_cast< MedianType * >( filter->GetModifiableInputFilter() );

  // std::cout << "callback! slice: " << filter->GetSliceIndex() << std::endl;

  // set half of the slice number as radius
  MedianType::InputSizeType radius;
  radius.Fill( filter->GetSliceIndex() / 2 );
  median->SetRadius( radius );
}

int itkSliceBySliceImageFilterTest(int argc, char * argv[])
{

  if( argc != 4 )
    {
    std::cerr << "usage: " << argv[0] << " input output slicingDimension" << std::endl;
    return EXIT_FAILURE;
    }

  const int                 Dimension = 3;
  typedef unsigned char     PixelType;

  typedef itk::Image< PixelType, Dimension >      ImageType;

  typedef itk::ImageFileReader< ImageType >       ReaderType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  typedef itk::SliceBySliceImageFilter< ImageType, ImageType > FilterType;

  FilterType::Pointer filter = FilterType::New();
  filter->DebugOn();

  filter->SetInput( reader->GetOutput() );

  typedef itk::MedianImageFilter< FilterType::InternalInputImageType,
                                  FilterType::InternalOutputImageType > MedianType;

  MedianType::Pointer median = MedianType::New();
  filter->SetFilter( median );

  typedef itk::PipelineMonitorImageFilter<FilterType::InternalOutputImageType> MonitorType;
  MonitorType::Pointer monitor = MonitorType::New();

  itk::CStyleCommand::Pointer command = itk::CStyleCommand::New();
  command->SetCallback( *sliceCallBack );

  filter->AddObserver( itk::IterationEvent(), command );

  itk::SimpleFilterWatcher watcher(filter, "filter");

  typedef itk::ImageFileWriter< ImageType > WriterType;

  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( filter->GetOutput() );
  writer->SetFileName( argv[2] );

  unsigned int slicingDimension;
  std::istringstream istrm( argv[3] );
  istrm >> slicingDimension;
  filter->SetDimension( slicingDimension );
  std::cout << "Slicing dimension: " << slicingDimension << std::endl;
  std::cout << "Slicing dimension: " << filter->GetDimension() << std::endl;

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  // set up a requested region of just one pixel and verify that was
  // all that was produced.
  std::cout << "Testing with requested region..." << std::endl;
  ImageType::Pointer temp = filter->GetOutput();
  temp->DisconnectPipeline();
  temp = ITK_NULLPTR;

  ImageType::RegionType rr = reader->GetOutput()->GetLargestPossibleRegion();
  for (unsigned int i = 0; i < ImageType::ImageDimension; ++i)
    {
    rr.SetIndex(i, rr.GetIndex(i)+rr.GetSize(i)/2);
    rr.SetSize(i,1);
    }

  monitor->SetInput(median->GetOutput());
  filter->SetOutputFilter(monitor);
  filter->GetOutput()->SetRequestedRegion(rr);

  try
    {
    filter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  // check that one slice executed is just one pixel and the input
  // filter just update that region
  TEST_EXPECT_EQUAL( monitor->GetNumberOfUpdates(), 1 );
  TEST_EXPECT_EQUAL( monitor->GetOutputRequestedRegions()[0].GetNumberOfPixels(), 1 );
  TEST_EXPECT_TRUE( monitor->VerifyAllInputCanStream(1) );

  //
  // Test that a sliced version of the input image information is passed
  // through to the internal filters
  //
  ImageType::Pointer image = ImageType::New();
  image->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
  image->Allocate();
  ImageType::SpacingType spacing;
  ImageType::PointType origin;
  for ( unsigned int i = 0; i < ImageType::ImageDimension; ++i )
    {
    spacing[i] = i + 0.1;
    origin[i] = i + 0.2;
    }
  image->SetSpacing(spacing);
  image->SetOrigin(origin);

  filter->SetInput(image);
  filter->Update();

  FilterType::InternalInputImageType::SpacingType expectedInternalSpacing;
  FilterType::InternalInputImageType::PointType expectedInternalOrigin;
  for ( unsigned int i = 0, internal_i = 0; internal_i < FilterType::InternalImageDimension; ++i, ++internal_i )
    {
    if ( i == slicingDimension )
      {
      ++i;
      }

    expectedInternalSpacing[internal_i] = spacing[i];
    expectedInternalOrigin[internal_i] = origin[i];
    }
  TEST_EXPECT_EQUAL( monitor->GetUpdatedOutputSpacing(), expectedInternalSpacing );
  TEST_EXPECT_EQUAL( monitor->GetUpdatedOutputOrigin(), expectedInternalOrigin );

  //
  // Exercise PrintSelf()
  //
  filter->Print( std::cout );

  //
  // Exercise exceptions
  //
  bool caughtException;
  FilterType::Pointer badFilter = FilterType::New();

  std::cout << "Testing with no filter set..." << std::endl;
  badFilter->SetInput( reader->GetOutput() );
  caughtException = false;
  try
    {
    badFilter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cout << "Caught expected exception" << std::endl;
    std::cout << excp << std::endl;
    caughtException = true;
    }
  if (!caughtException)
    {
    return EXIT_FAILURE;
    }

  std::cout << "Testing with no output filter set..." << std::endl;
  badFilter->SetInput( reader->GetOutput() );
  badFilter->SetInputFilter( median );
  caughtException = false;
  try
    {
    badFilter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cout << "Caught expected exception" << std::endl;
    std::cout << excp << std::endl;
    caughtException = true;
    }
  if (!caughtException)
    {
    return EXIT_FAILURE;
    }

  // check NULL input/output
  TRY_EXPECT_EXCEPTION(badFilter->SetInputFilter(ITK_NULLPTR));
  TRY_EXPECT_EXCEPTION(badFilter->SetOutputFilter(ITK_NULLPTR));

  return EXIT_SUCCESS;
}
<commit_msg>COMP: Valgrind detects uninitialized memory read<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  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.txt
 *
 *  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.
 *
 *=========================================================================*/

#include "itkSliceBySliceImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkSimpleFilterWatcher.h"
#include "itkPipelineMonitorImageFilter.h"
#include "itkTestingMacros.h"
#include "itkMedianImageFilter.h"

void sliceCallBack(itk::Object* object, const itk::EventObject &, void*)
{
  // the same typedefs than in the main function - should be done in a nicer way
  const int                 Dimension = 3;
  typedef unsigned char     PixelType;

  typedef itk::Image< PixelType, Dimension >                   ImageType;
  typedef itk::SliceBySliceImageFilter< ImageType, ImageType > FilterType;
  typedef itk::MedianImageFilter< FilterType::InternalInputImageType,
    FilterType::InternalOutputImageType >                      MedianType;

  // real stuff begins here
  // get the slice by slice filter and the median filter
  FilterType * filter = dynamic_cast< FilterType * >( object );
  MedianType * median = dynamic_cast< MedianType * >( filter->GetModifiableInputFilter() );

  // std::cout << "callback! slice: " << filter->GetSliceIndex() << std::endl;

  // set half of the slice number as radius
  MedianType::InputSizeType radius;
  radius.Fill( filter->GetSliceIndex() / 2 );
  median->SetRadius( radius );
}

int itkSliceBySliceImageFilterTest(int argc, char * argv[])
{

  if( argc != 4 )
    {
    std::cerr << "usage: " << argv[0] << " input output slicingDimension" << std::endl;
    return EXIT_FAILURE;
    }

  const int                 Dimension = 3;
  typedef unsigned char     PixelType;

  typedef itk::Image< PixelType, Dimension >      ImageType;

  typedef itk::ImageFileReader< ImageType >       ReaderType;

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );

  typedef itk::SliceBySliceImageFilter< ImageType, ImageType > FilterType;

  FilterType::Pointer filter = FilterType::New();
  filter->DebugOn();

  filter->SetInput( reader->GetOutput() );

  typedef itk::MedianImageFilter< FilterType::InternalInputImageType,
                                  FilterType::InternalOutputImageType > MedianType;

  MedianType::Pointer median = MedianType::New();
  filter->SetFilter( median );

  typedef itk::PipelineMonitorImageFilter<FilterType::InternalOutputImageType> MonitorType;
  MonitorType::Pointer monitor = MonitorType::New();

  itk::CStyleCommand::Pointer command = itk::CStyleCommand::New();
  command->SetCallback( *sliceCallBack );

  filter->AddObserver( itk::IterationEvent(), command );

  itk::SimpleFilterWatcher watcher(filter, "filter");

  typedef itk::ImageFileWriter< ImageType > WriterType;

  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( filter->GetOutput() );
  writer->SetFileName( argv[2] );

  unsigned int slicingDimension;
  std::istringstream istrm( argv[3] );
  istrm >> slicingDimension;
  filter->SetDimension( slicingDimension );
  std::cout << "Slicing dimension: " << slicingDimension << std::endl;
  std::cout << "Slicing dimension: " << filter->GetDimension() << std::endl;

  try
    {
    writer->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  // set up a requested region of just one pixel and verify that was
  // all that was produced.
  std::cout << "Testing with requested region..." << std::endl;
  ImageType::Pointer temp = filter->GetOutput();
  temp->DisconnectPipeline();
  temp = ITK_NULLPTR;

  ImageType::RegionType rr = reader->GetOutput()->GetLargestPossibleRegion();
  for (unsigned int i = 0; i < ImageType::ImageDimension; ++i)
    {
    rr.SetIndex(i, rr.GetIndex(i)+rr.GetSize(i)/2);
    rr.SetSize(i,1);
    }

  monitor->SetInput(median->GetOutput());
  filter->SetOutputFilter(monitor);
  filter->GetOutput()->SetRequestedRegion(rr);

  try
    {
    filter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  // check that one slice executed is just one pixel and the input
  // filter just update that region
  TEST_EXPECT_EQUAL( monitor->GetNumberOfUpdates(), 1 );
  TEST_EXPECT_EQUAL( monitor->GetOutputRequestedRegions()[0].GetNumberOfPixels(), 1 );
  TEST_EXPECT_TRUE( monitor->VerifyAllInputCanStream(1) );

  //
  // Test that a sliced version of the input image information is passed
  // through to the internal filters
  //
  ImageType::Pointer image = ImageType::New();
  image->SetRegions(reader->GetOutput()->GetLargestPossibleRegion());
  image->Allocate(true);
  ImageType::SpacingType spacing;
  ImageType::PointType origin;
  for ( unsigned int i = 0; i < ImageType::ImageDimension; ++i )
    {
    spacing[i] = i + 0.1;
    origin[i] = i + 0.2;
    }
  image->SetSpacing(spacing);
  image->SetOrigin(origin);

  filter->SetInput(image);
  filter->Update();

  FilterType::InternalInputImageType::SpacingType expectedInternalSpacing;
  FilterType::InternalInputImageType::PointType expectedInternalOrigin;
  for ( unsigned int i = 0, internal_i = 0; internal_i < FilterType::InternalImageDimension; ++i, ++internal_i )
    {
    if ( i == slicingDimension )
      {
      ++i;
      }

    expectedInternalSpacing[internal_i] = spacing[i];
    expectedInternalOrigin[internal_i] = origin[i];
    }
  TEST_EXPECT_EQUAL( monitor->GetUpdatedOutputSpacing(), expectedInternalSpacing );
  TEST_EXPECT_EQUAL( monitor->GetUpdatedOutputOrigin(), expectedInternalOrigin );

  //
  // Exercise PrintSelf()
  //
  filter->Print( std::cout );

  //
  // Exercise exceptions
  //
  bool caughtException;
  FilterType::Pointer badFilter = FilterType::New();

  std::cout << "Testing with no filter set..." << std::endl;
  badFilter->SetInput( reader->GetOutput() );
  caughtException = false;
  try
    {
    badFilter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cout << "Caught expected exception" << std::endl;
    std::cout << excp << std::endl;
    caughtException = true;
    }
  if (!caughtException)
    {
    return EXIT_FAILURE;
    }

  std::cout << "Testing with no output filter set..." << std::endl;
  badFilter->SetInput( reader->GetOutput() );
  badFilter->SetInputFilter( median );
  caughtException = false;
  try
    {
    badFilter->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cout << "Caught expected exception" << std::endl;
    std::cout << excp << std::endl;
    caughtException = true;
    }
  if (!caughtException)
    {
    return EXIT_FAILURE;
    }

  // check NULL input/output
  TRY_EXPECT_EXCEPTION(badFilter->SetInputFilter(ITK_NULLPTR));
  TRY_EXPECT_EXCEPTION(badFilter->SetOutputFilter(ITK_NULLPTR));

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                   OpenSim:  testOptimizationExample.cpp                    *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Cassidy Kelly                                                   *
 *                                                                            *
 * 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.                                             *
 * -------------------------------------------------------------------------- */

// Author: Cassidy Kelly

//==============================================================================
//==============================================================================

#include <OpenSim/OpenSim.h>
#include <OpenSim/Auxiliary/auxiliaryTestFunctions.h>
#include <istream>

using namespace OpenSim;
using namespace std;

#define ARM26_DESIGN_SPACE_DIM 6
#define REF_MAX_VEL 5.43

// Reference solution used for testing.
const static double refControls[ARM26_DESIGN_SPACE_DIM] = {0.01, 0.01, 0.0639327, 0.99, 0.99, 0.72858};

int main()
{
	try {
		Storage result("Arm26_noActivation_states.sto"), standard("std_Arm26_noActivation_states.sto");
		CHECK_STORAGE_AGAINST_STANDARD(result, standard, Array<double>(0.01, 16), __FILE__, __LINE__, "Arm26 no activation states failed");
		cout << "Arm26 no activation states passed\n";

		// Check the optimization result acheived at least a velocity of 5.43 m/s, and that the control values are within 20% of the reference values.
		ifstream resFile;
		resFile.open("Arm26_optimization_result");
		ASSERT(resFile.is_open(), __FILE__, __LINE__, "Can't open optimization result file" );

		vector<double> resVec;
		for ( ; ; ) {
			double tmp;
			resFile >> tmp;
			if (!resFile.good())
				break;
			resVec.push_back(tmp);
		}

		ASSERT(resVec.size() == ARM26_DESIGN_SPACE_DIM+1, __FILE__, __LINE__, "Optimization result size mismatch" );

		for (int i = 0; i < ARM26_DESIGN_SPACE_DIM-1; i++) {
			ASSERT(fabs(resVec[i] - refControls[i])/refControls[i] < 0.2, __FILE__, __LINE__, "Control value does not match reference" );
		}

		ASSERT(resVec[ARM26_DESIGN_SPACE_DIM+1] < REF_MAX_VEL, __FILE__, __LINE__, "Optimized velocity smaller than reference" );

		cout << "Arm26 optimization results passed\n";
	}
	catch (const Exception& e) {
        e.print(cerr);
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}
<commit_msg>fixed off-by-1 error...oops<commit_after>/* -------------------------------------------------------------------------- *
 *                   OpenSim:  testOptimizationExample.cpp                    *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Cassidy Kelly                                                   *
 *                                                                            *
 * 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.                                             *
 * -------------------------------------------------------------------------- */

// Author: Cassidy Kelly

//==============================================================================
//==============================================================================

#include <OpenSim/OpenSim.h>
#include <OpenSim/Auxiliary/auxiliaryTestFunctions.h>
#include <istream>

using namespace OpenSim;
using namespace std;

#define ARM26_DESIGN_SPACE_DIM 6
#define REF_MAX_VEL 5.43

// Reference solution used for testing.
const static double refControls[ARM26_DESIGN_SPACE_DIM] = {0.01, 0.01, 0.0639327, 0.99, 0.99, 0.72858};

int main()
{
	try {
		Storage result("Arm26_noActivation_states.sto"), standard("std_Arm26_noActivation_states.sto");
		CHECK_STORAGE_AGAINST_STANDARD(result, standard, Array<double>(0.01, 16), __FILE__, __LINE__, "Arm26 no activation states failed");
		cout << "Arm26 no activation states passed\n";

		// Check the optimization result acheived at least a velocity of 5.43 m/s, and that the control values are within 20% of the reference values.
		ifstream resFile;
		resFile.open("Arm26_optimization_result");
		ASSERT(resFile.is_open(), __FILE__, __LINE__, "Can't open optimization result file" );

		vector<double> resVec;
		for ( ; ; ) {
			double tmp;
			resFile >> tmp;
			if (!resFile.good())
				break;
			resVec.push_back(tmp);
		}

		ASSERT(resVec.size() == ARM26_DESIGN_SPACE_DIM+1, __FILE__, __LINE__, "Optimization result size mismatch" );

		for (int i = 0; i < ARM26_DESIGN_SPACE_DIM-1; i++) {
			ASSERT(fabs(resVec[i] - refControls[i])/refControls[i] < 0.2, __FILE__, __LINE__, "Control value does not match reference" );
		}
		ASSERT(resVec[ARM26_DESIGN_SPACE_DIM] > REF_MAX_VEL, __FILE__, __LINE__, "Optimized velocity smaller than reference" );

		cout << "Arm26 optimization results passed\n";
	}
	catch (const Exception& e) {
        e.print(cerr);
        return 1;
    }
    cout << "Done" << endl;
    return 0;
}
<|endoftext|>


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

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

=========================================================================*/

// TubeTK includes
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "tubeMessage.h"

// TubeTKITK includes
#include "tubeSegmentUsingOtsuThreshold.h"

// ITK includes
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkTimeProbesCollectorBase.h>

#include "SegmentUsingOtsuThresholdCLP.h"

template< class TPixel, unsigned int VDimension >
int DoIt( int argc, char * argv[] );

// Must follow include of "...CLP.h" and forward declaration of int DoIt( ... ).
#include "tubeCLIHelperFunctions.h"

template< class TPixel, unsigned int VDimension >
int DoIt( int argc, char * argv[] )
{
  PARSE_ARGS;

  // setup progress reporting
  double progress = 0.0;

  tube::CLIProgressReporter progressReporter(
    "SegmentUsingOtsuThreshold", CLPProcessInformation );
  progressReporter.Start();
  progressReporter.Report( progress );

  // The timeCollector to perform basic profiling of algorithmic components
  itk::TimeProbesCollectorBase timeCollector;

  // typedefs
  typedef tube::SegmentUsingOtsuThreshold< TPixel, VDimension > FilterType;

  // Load input image
  timeCollector.Start("Load data");

  typedef typename FilterType::InputImageType     InputImageType;
  typedef itk::ImageFileReader< InputImageType >  ImageReaderType;

  typename ImageReaderType::Pointer inputReader = ImageReaderType::New();

  try
    {
    inputReader->SetFileName( inputVolume.c_str() );
    inputReader->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    tube::ErrorMessage( "Error loading input image: "
                        + std::string(err.GetDescription()) );
    timeCollector.Report();
    return EXIT_FAILURE;
    }

  // Load mask image if provided
  typedef typename FilterType::MaskImageType     MaskImageType;
  typedef itk::ImageFileReader< MaskImageType >  MaskReaderType;

  typename MaskReaderType::Pointer maskReader = MaskReaderType::New();

  if( maskVolume.size() > 0 )
    {
    try
      {
      maskReader->SetFileName( maskVolume.c_str() );
      maskReader->Update();
      }
    catch( itk::ExceptionObject & err )
      {
      tube::ErrorMessage( "Error reading input mask: "
                          + std::string(err.GetDescription()) );
      timeCollector.Report();
      return EXIT_FAILURE;
      }
    }

  timeCollector.Stop("Load data");
  progress = 0.1;
  progressReporter.Report( progress );

  // run otsu thresholding
  timeCollector.Start("Otsu thresholding");

  typename FilterType::Pointer filter = FilterType::New();

  filter->SetInput( inputReader->GetOutput() );

  if( maskVolume.size() > 0 )
    {
    filter->SetMaskValue( maskValue );
    filter->SetMaskImage( maskReader->GetOutput() );
    }

  filter->Update();

  std::cout << "Chosen threshold = " << filter->GetThreshold() << std::endl;

  timeCollector.Stop("Otsu thresholding");
  progress = 0.8; // At about 80% done
  progressReporter.Report( progress );

  // write output
  typedef typename FilterType::OutputImageType      OutputImageType;
  typedef itk::ImageFileWriter< OutputImageType >   OutputWriterType;

  timeCollector.Start("Write segmentation mask");

  typename OutputWriterType::Pointer writer = OutputWriterType::New();

  try
    {
    writer->SetFileName( outputVolume.c_str() );
    writer->SetInput( filter->GetOutput() );
    writer->SetUseCompression( true );
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    tube::ErrorMessage( "Error writing segmentation mask: "
                        + std::string(err.GetDescription()) );
    timeCollector.Report();
    return EXIT_FAILURE;
    }

  timeCollector.Stop("Write segmentation mask");
  progress = 1.0;
  progressReporter.Report( progress );
  progressReporter.End();
  timeCollector.Report();

  return EXIT_SUCCESS;
}

// Main
int main( int argc, char * argv[] )
{
  PARSE_ARGS;

  // You may need to update this line if, in the project's .xml CLI file,
  //   you change the variable name for the inputVolume.
  return tube::ParseArgsAndCallDoIt( inputVolume, argc, argv );
}
<commit_msg>Small style change in SegmentUsingOtsuThreshold<commit_after>/*=========================================================================

Library:   TubeTK

Copyright 2010 Kitware Inc. 28 Corporate Drive,
Clifton Park, NY, 12065, USA.

All rights reserved.

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.

=========================================================================*/

// ITK includes
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkTimeProbesCollectorBase.h>

// TubeTKITK includes
#include "tubeSegmentUsingOtsuThreshold.h"

// TubeTK includes
#include "tubeCLIFilterWatcher.h"
#include "tubeCLIProgressReporter.h"
#include "tubeMessage.h"

#include "SegmentUsingOtsuThresholdCLP.h"

template< class TPixel, unsigned int VDimension >
int DoIt( int argc, char * argv[] );

// Must follow include of "...CLP.h" and forward declaration of int DoIt( ... ).
#include "tubeCLIHelperFunctions.h"

template< class TPixel, unsigned int VDimension >
int DoIt( int argc, char * argv[] )
{
  PARSE_ARGS;

  // setup progress reporting
  double progress = 0.0;

  tube::CLIProgressReporter progressReporter(
    "SegmentUsingOtsuThreshold", CLPProcessInformation );
  progressReporter.Start();
  progressReporter.Report( progress );

  // The timeCollector to perform basic profiling of algorithmic components
  itk::TimeProbesCollectorBase timeCollector;

  // typedefs
  typedef tube::SegmentUsingOtsuThreshold< TPixel, VDimension > FilterType;

  // Load input image
  timeCollector.Start("Load data");

  typedef typename FilterType::InputImageType     InputImageType;
  typedef itk::ImageFileReader< InputImageType >  ImageReaderType;

  typename ImageReaderType::Pointer inputReader = ImageReaderType::New();

  try
    {
    inputReader->SetFileName( inputVolume.c_str() );
    inputReader->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    tube::ErrorMessage( "Error loading input image: "
                        + std::string(err.GetDescription()) );
    timeCollector.Report();
    return EXIT_FAILURE;
    }

  // Load mask image if provided
  typedef typename FilterType::MaskImageType     MaskImageType;
  typedef itk::ImageFileReader< MaskImageType >  MaskReaderType;

  typename MaskReaderType::Pointer maskReader = MaskReaderType::New();

  if( maskVolume.size() > 0 )
    {
    try
      {
      maskReader->SetFileName( maskVolume.c_str() );
      maskReader->Update();
      }
    catch( itk::ExceptionObject & err )
      {
      tube::ErrorMessage( "Error reading input mask: "
                          + std::string(err.GetDescription()) );
      timeCollector.Report();
      return EXIT_FAILURE;
      }
    }

  timeCollector.Stop("Load data");
  progress = 0.1;
  progressReporter.Report( progress );

  // run otsu thresholding
  timeCollector.Start("Otsu thresholding");

  typename FilterType::Pointer filter = FilterType::New();

  filter->SetInput( inputReader->GetOutput() );

  if( maskVolume.size() > 0 )
    {
    filter->SetMaskValue( maskValue );
    filter->SetMaskImage( maskReader->GetOutput() );
    }

  filter->Update();

  std::cout << "Chosen threshold = " << filter->GetThreshold() << std::endl;

  timeCollector.Stop("Otsu thresholding");
  progress = 0.8; // At about 80% done
  progressReporter.Report( progress );

  // write output
  typedef typename FilterType::OutputImageType      OutputImageType;
  typedef itk::ImageFileWriter< OutputImageType >   OutputWriterType;

  timeCollector.Start("Write segmentation mask");

  typename OutputWriterType::Pointer writer = OutputWriterType::New();

  try
    {
    writer->SetFileName( outputVolume.c_str() );
    writer->SetInput( filter->GetOutput() );
    writer->SetUseCompression( true );
    writer->Update();
    }
  catch( itk::ExceptionObject & err )
    {
    tube::ErrorMessage( "Error writing segmentation mask: "
                        + std::string(err.GetDescription()) );
    timeCollector.Report();
    return EXIT_FAILURE;
    }

  timeCollector.Stop("Write segmentation mask");
  progress = 1.0;
  progressReporter.Report( progress );
  progressReporter.End();
  timeCollector.Report();

  return EXIT_SUCCESS;
}

// Main
int main( int argc, char * argv[] )
{
  PARSE_ARGS;

  // You may need to update this line if, in the project's .xml CLI file,
  //   you change the variable name for the inputVolume.
  return tube::ParseArgsAndCallDoIt( inputVolume, argc, argv );
}
<|endoftext|>


<commit_before>#include "master.hpp"

namespace factor
{

bool factor_vm::fatal_erroring_p;

static inline void fa_diddly_atal_error()
{
	printf("fatal_error in fatal_error!\n");
	breakpoint();
	::_exit(86);
}

void fatal_error(const char *msg, cell tagged)
{
	if (factor_vm::fatal_erroring_p)
		fa_diddly_atal_error();

	factor_vm::fatal_erroring_p = true;

	std::cout << "fatal_error: " << msg;
	std::cout << ": " << (void*)tagged;
	std::cout << std::endl;
	abort();
}

void critical_error(const char *msg, cell tagged)
{
	std::cout << "You have triggered a bug in Factor. Please report.\n";
	std::cout << "critical_error: " << msg;
	std::cout << ": " << std::hex << tagged << std::dec;
	std::cout << std::endl;
	current_vm()->factorbug();
}

void out_of_memory()
{
	std::cout << "Out of memory\n\n";
	current_vm()->dump_generations();
	abort();
}

void factor_vm::general_error(vm_error_type error, cell arg1, cell arg2)
{
	faulting_p = true;

	/* Reset local roots before allocating anything */
	data_roots.clear();
	bignum_roots.clear();
	code_roots.clear();

	/* If we had an underflow or overflow, data or retain stack
	pointers might be out of bounds, so fix them before allocating
	anything */
	ctx->fix_stacks();

	/* If error was thrown during heap scan, we re-enable the GC */
	gc_off = false;

	/* If the error handler is set, we rewind any C stack frames and
	pass the error to user-space. */
	if(!current_gc && to_boolean(special_objects[ERROR_HANDLER_QUOT]))
	{
#ifdef FACTOR_DEBUG
		/* Doing a GC here triggers all kinds of funny errors */
		primitive_compact_gc();
#endif

		/* Now its safe to allocate and GC */
		cell error_object = allot_array_4(special_objects[OBJ_ERROR],
			tag_fixnum(error),arg1,arg2);

		ctx->push(error_object);

		/* The unwind-native-frames subprimitive will clear faulting_p
		if it was successfully reached. */
		unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],
			ctx->callstack_top);
	}
	/* Error was thrown in early startup before error handler is set, so just
	crash. */
	else
	{
		std::cout << "You have triggered a bug in Factor. Please report.\n";
		std::cout << "error: " << error << std::endl;
		std::cout << "arg 1: "; print_obj(arg1); std::cout << std::endl;
		std::cout << "arg 2: "; print_obj(arg2); std::cout << std::endl;
		factorbug();
		abort();
	}
}

void factor_vm::type_error(cell type, cell tagged)
{
	general_error(ERROR_TYPE,tag_fixnum(type),tagged);
}

void factor_vm::not_implemented_error()
{
	general_error(ERROR_NOT_IMPLEMENTED,false_object,false_object);
}

void factor_vm::verify_memory_protection_error(cell addr)
{
	/* Called from the OS-specific top halves of the signal handlers to
	make sure it's safe to dispatch to memory_protection_error */
	if(fatal_erroring_p)
		fa_diddly_atal_error();
	if(faulting_p && !code->safepoint_p(addr))
		fatal_error("Double fault", addr);
	else if(fep_p)
		fatal_error("Memory protection fault during low-level debugger", addr);
	else if(atomic::load(&current_gc_p))
		fatal_error("Memory protection fault during gc", addr);
}

void factor_vm::memory_protection_error(cell pc, cell addr)
{
	if(code->safepoint_p(addr))
		safepoint.handle_safepoint(this, pc);
	else if(ctx->datastack_seg->underflow_p(addr))
		general_error(ERROR_DATASTACK_UNDERFLOW,false_object,false_object);
	else if(ctx->datastack_seg->overflow_p(addr))
		general_error(ERROR_DATASTACK_OVERFLOW,false_object,false_object);
	else if(ctx->retainstack_seg->underflow_p(addr))
		general_error(ERROR_RETAINSTACK_UNDERFLOW,false_object,false_object);
	else if(ctx->retainstack_seg->overflow_p(addr))
		general_error(ERROR_RETAINSTACK_OVERFLOW,false_object,false_object);
	else if(ctx->callstack_seg->underflow_p(addr))
		general_error(ERROR_CALLSTACK_OVERFLOW,false_object,false_object);
	else if(ctx->callstack_seg->overflow_p(addr))
		general_error(ERROR_CALLSTACK_UNDERFLOW,false_object,false_object);
	else
		general_error(ERROR_MEMORY,from_unsigned_cell(addr),false_object);
}

void factor_vm::signal_error(cell signal)
{
	general_error(ERROR_SIGNAL,from_unsigned_cell(signal),false_object);
}

void factor_vm::divide_by_zero_error()
{
	general_error(ERROR_DIVIDE_BY_ZERO,false_object,false_object);
}

void factor_vm::fp_trap_error(unsigned int fpu_status)
{
	general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),false_object);
}

/* For testing purposes */
void factor_vm::primitive_unimplemented()
{
	not_implemented_error();
}

void factor_vm::memory_signal_handler_impl()
{
	memory_protection_error(signal_fault_pc, signal_fault_addr);
	if (!signal_resumable)
	{
		/* In theory we should only get here if the callstack overflowed during a
		safepoint */
		general_error(ERROR_CALLSTACK_OVERFLOW,false_object,false_object);
	}
}

void memory_signal_handler_impl()
{
	current_vm()->memory_signal_handler_impl();
}

void factor_vm::synchronous_signal_handler_impl()
{
	signal_error(signal_number);
}

void synchronous_signal_handler_impl()
{
	current_vm()->synchronous_signal_handler_impl();
}

void factor_vm::fp_signal_handler_impl()
{
	/* Clear pending exceptions to avoid getting stuck in a loop */
	set_fpu_state(get_fpu_state());

	fp_trap_error(signal_fpu_status);
}

void fp_signal_handler_impl()
{
	current_vm()->fp_signal_handler_impl();
}
}
<commit_msg>errors.cpp: general_error() throws away its args when it calls compact_gc() when compiled with DEBUG=1. Save the args as data_roots instead. Fixes #615. See #620.<commit_after>#include "master.hpp"

namespace factor
{

bool factor_vm::fatal_erroring_p;

static inline void fa_diddly_atal_error()
{
	printf("fatal_error in fatal_error!\n");
	breakpoint();
	::_exit(86);
}

void fatal_error(const char *msg, cell tagged)
{
	if (factor_vm::fatal_erroring_p)
		fa_diddly_atal_error();

	factor_vm::fatal_erroring_p = true;

	std::cout << "fatal_error: " << msg;
	std::cout << ": " << (void*)tagged;
	std::cout << std::endl;
	abort();
}

void critical_error(const char *msg, cell tagged)
{
	std::cout << "You have triggered a bug in Factor. Please report.\n";
	std::cout << "critical_error: " << msg;
	std::cout << ": " << std::hex << tagged << std::dec;
	std::cout << std::endl;
	current_vm()->factorbug();
}

void out_of_memory()
{
	std::cout << "Out of memory\n\n";
	current_vm()->dump_generations();
	abort();
}

void factor_vm::general_error(vm_error_type error, cell arg1_, cell arg2_)
{
	faulting_p = true;

	/* Reset local roots before allocating anything */
	data_roots.clear();
	bignum_roots.clear();
	code_roots.clear();

	data_root<object> arg1(arg1_,this);
	data_root<object> arg2(arg2_,this);

	/* If we had an underflow or overflow, data or retain stack
	pointers might be out of bounds, so fix them before allocating
	anything */
	ctx->fix_stacks();

	/* If error was thrown during heap scan, we re-enable the GC */
	gc_off = false;

	/* If the error handler is set, we rewind any C stack frames and
	pass the error to user-space. */
	if(!current_gc && to_boolean(special_objects[ERROR_HANDLER_QUOT]))
	{
#ifdef FACTOR_DEBUG
		/* Doing a GC here triggers all kinds of funny errors */
		primitive_compact_gc();
#endif

		/* Now its safe to allocate and GC */
		cell error_object = allot_array_4(special_objects[OBJ_ERROR],
			tag_fixnum(error),arg1.value(),arg2.value());

		ctx->push(error_object);

		/* The unwind-native-frames subprimitive will clear faulting_p
		if it was successfully reached. */
		unwind_native_frames(special_objects[ERROR_HANDLER_QUOT],
			ctx->callstack_top);
	}
	/* Error was thrown in early startup before error handler is set, so just
	crash. */
	else
	{
		std::cout << "You have triggered a bug in Factor. Please report.\n";
		std::cout << "error: " << error << std::endl;
		std::cout << "arg 1: "; print_obj(arg1.value()); std::cout << std::endl;
		std::cout << "arg 2: "; print_obj(arg2.value()); std::cout << std::endl;
		factorbug();
		abort();
	}
}

void factor_vm::type_error(cell type, cell tagged)
{
	general_error(ERROR_TYPE,tag_fixnum(type),tagged);
}

void factor_vm::not_implemented_error()
{
	general_error(ERROR_NOT_IMPLEMENTED,false_object,false_object);
}

void factor_vm::verify_memory_protection_error(cell addr)
{
	/* Called from the OS-specific top halves of the signal handlers to
	make sure it's safe to dispatch to memory_protection_error */
	if(fatal_erroring_p)
		fa_diddly_atal_error();
	if(faulting_p && !code->safepoint_p(addr))
		fatal_error("Double fault", addr);
	else if(fep_p)
		fatal_error("Memory protection fault during low-level debugger", addr);
	else if(atomic::load(&current_gc_p))
		fatal_error("Memory protection fault during gc", addr);
}

void factor_vm::memory_protection_error(cell pc, cell addr)
{
	if(code->safepoint_p(addr))
		safepoint.handle_safepoint(this, pc);
	else if(ctx->datastack_seg->underflow_p(addr))
		general_error(ERROR_DATASTACK_UNDERFLOW,false_object,false_object);
	else if(ctx->datastack_seg->overflow_p(addr))
		general_error(ERROR_DATASTACK_OVERFLOW,false_object,false_object);
	else if(ctx->retainstack_seg->underflow_p(addr))
		general_error(ERROR_RETAINSTACK_UNDERFLOW,false_object,false_object);
	else if(ctx->retainstack_seg->overflow_p(addr))
		general_error(ERROR_RETAINSTACK_OVERFLOW,false_object,false_object);
	else if(ctx->callstack_seg->underflow_p(addr))
		general_error(ERROR_CALLSTACK_OVERFLOW,false_object,false_object);
	else if(ctx->callstack_seg->overflow_p(addr))
		general_error(ERROR_CALLSTACK_UNDERFLOW,false_object,false_object);
	else
		general_error(ERROR_MEMORY,from_unsigned_cell(addr),false_object);
}

void factor_vm::signal_error(cell signal)
{
	general_error(ERROR_SIGNAL,from_unsigned_cell(signal),false_object);
}

void factor_vm::divide_by_zero_error()
{
	general_error(ERROR_DIVIDE_BY_ZERO,false_object,false_object);
}

void factor_vm::fp_trap_error(unsigned int fpu_status)
{
	general_error(ERROR_FP_TRAP,tag_fixnum(fpu_status),false_object);
}

/* For testing purposes */
void factor_vm::primitive_unimplemented()
{
	not_implemented_error();
}

void factor_vm::memory_signal_handler_impl()
{
	memory_protection_error(signal_fault_pc, signal_fault_addr);
	if (!signal_resumable)
	{
		/* In theory we should only get here if the callstack overflowed during a
		safepoint */
		general_error(ERROR_CALLSTACK_OVERFLOW,false_object,false_object);
	}
}

void memory_signal_handler_impl()
{
	current_vm()->memory_signal_handler_impl();
}

void factor_vm::synchronous_signal_handler_impl()
{
	signal_error(signal_number);
}

void synchronous_signal_handler_impl()
{
	current_vm()->synchronous_signal_handler_impl();
}

void factor_vm::fp_signal_handler_impl()
{
	/* Clear pending exceptions to avoid getting stuck in a loop */
	set_fpu_state(get_fpu_state());

	fp_trap_error(signal_fpu_status);
}

void fp_signal_handler_impl()
{
	current_vm()->fp_signal_handler_impl();
}
}
<|endoftext|>