text:
// Copyright (c) 2013, German Neuroinformatics Node (G-Node)
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted under the terms of the BSD License. See
// LICENSE file in the root of the Project.

#include "TestOptionalObligatory.hpp"

#include <ctime>
#include <typeinfo>
#include <boost/any.hpp>

#include <nix/util/util.hpp>

using namespace std;
using namespace nix;

namespace test {
    template<typename T>
    bool TtoBool(T var) {
        return !!var;
    }
    template<>
    bool TtoBool<std::vector<std::string>>(std::vector<std::string> var) {
        return !(var.empty());
    }
    template<>
    bool TtoBool<std::vector<double>>(std::vector<double> var) {
        return !(var.empty());
    }
    template<>
    bool TtoBool<nix::Section>(nix::Section var) {
        return !(var.isNone());
    }
    template<>
    bool TtoBool<nix::DataArray>(nix::DataArray var) {
        return !(var.isNone());
    }
    template<>
    bool TtoBool<nix::LinkType>(nix::LinkType var) {
        return true; // LinkType as enum is always set
    }
    template<>
    bool TtoBool<std::vector<nix::Value>>(std::vector<nix::Value> var) {
        return !(var.empty());
    }
    template<>
    bool TtoBool<std::vector<nix::DataArray>>(std::vector<nix::DataArray> var) {
        return !(var.empty());
    }
    template<>
    bool TtoBool<std::vector<nix::Source>>(std::vector<nix::Source> var) {
        return !(var.empty());
    }
    template<>
    bool TtoBool<std::string>(std::string var) {
        return (var.length() > 0);
    }

    bool isValidOptional(bool is_opt, bool is_set, bool accepts_none) {
        return (is_opt && accepts_none);
    }

    bool isValidObligatory(bool is_opt, bool is_set, bool accepts_none) {
        return (!is_opt && !accepts_none && is_set);
    }
} // namespace test

void TestOptionalObligatory::setUp() {
    startup_time = time(NULL);

    // File-------------------------------------------------------------
    file = File::open("test_block.h5", FileMode::Overwrite);

    // Section---------------------------------------------------------
    section = file.createSection("foo_section", "metadata");

    // Block------------------------------------------------------------
    block = file.createBlock("block_one", "dataset");

    // property---------------------------------------------------------
    dummy = Value(10);
    property = section.createProperty("prop", dummy);

    // dataAray---------------------------------------------------------
    dataArray = block.createDataArray("dimensionTest", "test", DataType::Double, nix::NDSize({ 0 }));

    // tag--------------------------------------------------------
    vector<string> array_names = { "data_array_a", "data_array_b", "data_array_c",
                                   "data_array_d", "data_array_e" };

    tag = block.createTag("featureTest", "Test", {0.0, 2.0, 3.4});
    vector<DataArray> refs;
    for (const auto &name : array_names) {
        refs.push_back(block.createDataArray(name, "reference", DataType::Double, nix::NDSize({ 0 })));
    }
    tag.references(refs);

    // multiTag----------------------------------------------------------
    positions = block.createDataArray("positions_DataArray", "dataArray",
                                      DataType::Double, nix::NDSize({ 0 }));
    typedef boost::multi_array<double, 1> array_type;
    typedef array_type::index index;
    array_type A(boost::extents[5]);
    for(index i = 0; i < 5; ++i){
        A[i] = 100.0*i;
    }
    positions.setData(A);
    multiTag = block.createMultiTag("tag_one", "test_tag", positions);

    // source-----------------------------------------------------------
    source = block.createSource("source_one", "channel");

    // set_dimension-----------------------------------------------------
    set_dim = dataArray.appendSetDimension();

    // sampled_dimension-------------------------------------------------
    double samplingInterval = boost::math::constants::pi<double>();
    sampled_dim = dataArray.appendSampledDimension(samplingInterval);

    // range_dimension---------------------------------------------------
    std::vector<double> ticks;
    for (size_t i = 0; i < 5; i++) {
        ticks.push_back(i * boost::math::constants::pi<double>());
    }
    range_dim = dataArray.appendRangeDimension(ticks);

    // feature
    feature = tag.createFeature(dataArray, nix::LinkType::Tagged);
}

void TestOptionalObligatory::tearDown() {
    file.close();
}

void TestOptionalObligatory::testNamedEntityId() {
    static const bool accepts_none = test::accepts_noneT<nix::base::NamedEntity<base::INamedEntity>, test::id>::value;
    // using SFINAE if-else block instead of normal one to avoid "unreachable code" warnings
    // equivalent: std::is_class<decltype(block.id())>::value ? accepts_none : util::is_optional<decltype(block.id());
    is_opt   = std::conditional<std::is_class<decltype(block.id())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(block.id())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(block.id()));
    summarize("NamedEntity::id", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testNamedEntityType() {
    static const bool accepts_none = test::accepts_noneT<nix::base::NamedEntity<base::INamedEntity>, test::type>::value;
    is_opt   = std::conditional<std::is_class<decltype(block.type())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(block.type())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(block.type()));
    summarize("NamedEntity::type", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testNamedEntityName() {
    static const bool accepts_none = test::accepts_noneT<nix::base::NamedEntity<base::INamedEntity>, test::name>::value;
    is_opt   = std::conditional<std::is_class<decltype(block.name())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(block.name())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(block.name()));
    summarize("NamedEntity::name", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testNamedEntityDefinition() {
    static const bool accepts_none = test::accepts_noneT<nix::base::NamedEntity<base::INamedEntity>, test::definition>::value;
    is_opt   = std::conditional<std::is_class<decltype(block.definition())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(block.definition())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(block.definition()));
    summarize("NamedEntity::definition", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testEntityWithMetadataMetadata() {
    static const bool accepts_none = test::accepts_noneT<nix::base::EntityWithMetadata<base::IEntityWithMetadata>, test::metadata>::value;
    is_opt   = std::conditional<std::is_class<decltype(block.metadata())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(block.metadata())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(block.metadata()));
    summarize("EntityWithMetadata::metadata", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testEntityWithSourcesSources() {
    static const bool accepts_none = test::accepts_noneT<nix::base::EntityWithSources<base::IEntityWithSources>, test::sources>::value;
    is_opt   = std::conditional<std::is_class<decltype(block.sources())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(block.sources())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(block.sources()));
    summarize("EntityWithSources::sources", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testDataArrayLabel() {
    static const bool accepts_none = test::accepts_noneT<nix::DataArray, test::label>::value;
    is_opt   = std::conditional<std::is_class<decltype(dataArray.label())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(dataArray.label())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(dataArray.label()));
    summarize("DataArray::label", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testDataArrayUnit() {
    static const bool accepts_none = test::accepts_noneT<nix::DataArray, test::unit>::value;
    is_opt   = std::conditional<std::is_class<decltype(dataArray.unit())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(dataArray.unit())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(dataArray.unit()));
    summarize("DataArray::unit", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testDataArrayExpansionOrigin() {
    static const bool accepts_none = test::accepts_noneT<nix::DataArray, test::expansionOrigin>::value;
    is_opt   = std::conditional<std::is_class<decltype(dataArray.expansionOrigin())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(dataArray.expansionOrigin())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(dataArray.expansionOrigin()));
    summarize("DataArray::expansionOrigin", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSetDimensionIndex() {
    static const bool accepts_none = test::accepts_noneT<nix::SetDimension, test::index>::value;
    is_opt   = std::conditional<std::is_class<decltype(set_dim.index())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(set_dim.index())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(set_dim.index()));
    summarize("SetDimension::index", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSetDimensionLabels() {
    static const bool accepts_none = test::accepts_noneT<nix::SetDimension, test::labels>::value;
    is_opt   = std::conditional<std::is_class<decltype(set_dim.labels())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(set_dim.labels())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(set_dim.labels()));
    summarize("SetDimension::labels", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSampledDimensionIndex() {
    static const bool accepts_none = test::accepts_noneT<nix::SampledDimension, test::index>::value;
    is_opt   = std::conditional<std::is_class<decltype(sampled_dim.index())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(sampled_dim.index())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(sampled_dim.index()));
    summarize("SampledDimension::index", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSampledDimensionLabel() {
    static const bool accepts_none = test::accepts_noneT<nix::SampledDimension, test::label>::value;
    is_opt   = std::conditional<std::is_class<decltype(sampled_dim.label())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(sampled_dim.label())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(sampled_dim.label()));
    summarize("SampledDimension::label", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSampledDimensionOffset() {
    static const bool accepts_none = test::accepts_noneT<nix::SampledDimension, test::offset>::value;
    is_opt   = std::conditional<std::is_class<decltype(sampled_dim.offset())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(sampled_dim.offset())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(sampled_dim.offset()));
    summarize("SampledDimension::offset", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSampledDimensionSamplingInterval() {
    static const bool accepts_none = test::accepts_noneT<nix::SampledDimension, test::samplingInterval>::value;
    is_opt   = std::conditional<std::is_class<decltype(sampled_dim.samplingInterval())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(sampled_dim.samplingInterval())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(sampled_dim.samplingInterval()));
    summarize("SampledDimension::samplingInterval", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSampledDimensionUnit() {
    static const bool accepts_none = test::accepts_noneT<nix::SampledDimension, test::unit>::value;
    is_opt   = std::conditional<std::is_class<decltype(sampled_dim.unit())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(sampled_dim.unit())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(sampled_dim.unit()));
    summarize("SampledDimension::unit", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testRangeDimensionIndex() {
    static const bool accepts_none = test::accepts_noneT<nix::RangeDimension, test::index>::value;
    is_opt   = std::conditional<std::is_class<decltype(range_dim.index())>::value,
                                    std::integral_constant<bool, accepts_none>,
                                    std::integral_constant<bool, util::is_optional<decltype(range_dim.index())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(range_dim.index()));
    summarize("RangeDimension::index", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testRangeDimensionLabel() {
    static const bool accepts_none = test::accepts_noneT<nix::RangeDimension, test::label>::value;
    is_opt   = std::conditional<std::is_class<decltype(range_dim.label())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(range_dim.label())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(range_dim.label()));
    summarize("RangeDimension::label", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testRangeDimensionTicks() {
    static const bool accepts_none = test::accepts_noneT<nix::RangeDimension, test::ticks>::value;
    is_opt   = std::conditional<std::is_class<decltype(range_dim.ticks())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(range_dim.ticks())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(range_dim.ticks()));
    summarize("RangeDimension::ticks", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testRangeDimensionUnit() {
    static const bool accepts_none = test::accepts_noneT<nix::RangeDimension, test::unit>::value;
    is_opt   = std::conditional<std::is_class<decltype(range_dim.unit())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(range_dim.unit())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(range_dim.unit()));
    summarize("RangeDimension::unit", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testPropertyMapping() {
    static const bool accepts_none = test::accepts_noneT<nix::Property, test::mapping>::value;
    is_opt   = std::conditional<std::is_class<decltype(property.mapping())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(property.mapping())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(property.mapping()));
    summarize("Property::mapping", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testPropertyUnit() {
    static const bool accepts_none = test::accepts_noneT<nix::Property, test::unit>::value;
    is_opt   = std::conditional<std::is_class<decltype(property.unit())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(property.unit())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(util::deRef(property.unit()));
    summarize("Property::unit", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testPropertyValues() {
    static const bool accepts_none = test::accepts_noneT<nix::Property, test::values>::value;
    is_opt   = std::conditional<std::is_class<decltype(property.values())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(property.values())>::value>
                                    >::type::value;
    is_set   = test::TtoBool(property.values());
    summarize("Property::values", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testFeatureData() {
    static const bool accepts_none = test::accepts_noneT<nix::Feature, test::data>::value;
    is_opt   = std::conditional<std::is_class<decltype(feature.data())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(feature.data())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(feature.data()));
    summarize("Feature::data", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testFeatureLinkType() {
    static const bool accepts_none = test::accepts_noneT<nix::Feature, test::linkType>::value;
    is_opt   = std::conditional<std::is_class<decltype(feature.linkType())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(feature.linkType())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(feature.linkType()));
    summarize("Feature::linkType", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSectionLink() {
    static const bool accepts_none = test::accepts_noneT<nix::Section, test::link>::value;
    is_opt   = std::conditional<std::is_class<decltype(section.link())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(section.link())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(section.link()));
    summarize("Section::link", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSectionMapping() {
    static const bool accepts_none = test::accepts_noneT<nix::Section, test::mapping>::value;
    is_opt   = std::conditional<std::is_class<decltype(section.mapping())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(section.mapping())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(section.mapping()));
    summarize("Mapping::mapping", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testSectionRepository() {
    static const bool accepts_none = test::accepts_noneT<nix::Section, test::repository>::value;
    is_opt   = std::conditional<std::is_class<decltype(section.repository())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(section.repository())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(section.repository()));
    summarize("Repository::repository", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testTagExtent() {
    static const bool accepts_none = test::accepts_noneT<nix::Tag, test::extent>::value;
    is_opt   = std::conditional<std::is_class<decltype(tag.extent())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(tag.extent())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(tag.extent()));
    summarize("Tag::extent", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testTagPosition() {
    static const bool accepts_none = test::accepts_noneT<nix::Tag, test::position>::value;
    is_opt   = std::conditional<std::is_class<decltype(tag.position())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(tag.position())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(tag.position()));
    summarize("Tag::position", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testTagUnits() {
    static const bool accepts_none = test::accepts_noneT<nix::Tag, test::units>::value;
    is_opt   = std::conditional<std::is_class<decltype(tag.units())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(tag.units())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(tag.units()));
    summarize("Tag::units", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testMultiTagExtents() {
    static const bool accepts_none = test::accepts_noneT<nix::MultiTag, test::extents>::value;
    is_opt   = std::conditional<std::is_class<decltype(multiTag.extents())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(multiTag.extents())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(multiTag.extents()));
    summarize("MultiTag::extents", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::testMultiTagPositions() {
    static const bool accepts_none = test::accepts_noneT<nix::MultiTag, test::positions>::value;
    is_opt   = std::conditional<std::is_class<decltype(multiTag.positions())>::value,
                                std::integral_constant<bool, accepts_none>,
                                std::integral_constant<bool, util::is_optional<decltype(multiTag.positions())>::value>
                                >::type::value;
    is_set   = test::TtoBool(util::deRef(multiTag.positions()));
    summarize("MultiTag::positions", is_opt, is_set, accepts_none);
    CPPUNIT_ASSERT(test::isValidOptional(is_opt, is_set, accepts_none) ||
                   test::isValidObligatory(is_opt, is_set, accepts_none));
}

void TestOptionalObligatory::summarize(std::string name, bool is_opt, bool is_set, bool accepts_none)
{
    summary += name; summary += ": ";
    if(test::isValidOptional(is_opt, is_set, accepts_none)) {
        summary += "OPTIONAL";
    }
    else if(test::isValidObligatory(is_opt, is_set, accepts_none)) {
        summary += "OBLIGATORY";
    }
    else {
        summary += "FAIL"; summary += "\n    is_optional:"; summary += util::numToStr(is_opt);
        summary += "\n    is_set:"; summary += util::numToStr(is_set); summary += "\n    accepts_none:";
        summary += util::numToStr(accepts_none);
    }
    summary += "\n";
}


text:
#ifndef MPI_PYP_TOPICS_HH
#define MPI_PYP_TOPICS_HH

#include <vector>
#include <iostream>

#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/inversive_congruential.hpp>
#include <boost/random/linear_congruential.hpp>
#include <boost/random/lagged_fibonacci.hpp>
#include <boost/mpi/environment.hpp>
#include <boost/mpi/communicator.hpp>

#include "mpi-pyp.hh"
#include "mpi-corpus.hh"

class MPIPYPTopics {
public:
  typedef std::vector<int> DocumentTopics;
  typedef std::vector<DocumentTopics> CorpusTopics;
  typedef double F;

public:
  MPIPYPTopics(int num_topics, bool use_topic_pyp=false, unsigned long seed = 0)
    : m_num_topics(num_topics), m_word_pyps(1),
    m_topic_pyp(0.5,1.0), m_use_topic_pyp(use_topic_pyp),
    m_seed(seed),
    uni_dist(0,1), rng(seed == 0 ? (unsigned long)this : seed),
    rnd(rng, uni_dist), m_mpi_start(-1), m_mpi_end(-1) {
      boost::mpi::communicator m_world;
      m_rank = m_world.rank();
      m_size = m_world.size();
      m_am_root = (m_rank == 0);
    }

  void sample_corpus(const MPICorpus& corpus, int samples,
                     int freq_cutoff_start=0, int freq_cutoff_end=0,
                     int freq_cutoff_interval=0,
                     int max_contexts_per_document=0);

  int sample(const DocumentId& doc, const Term& term);
  std::pair<int,F> max(const DocumentId& doc, const Term& term) const;
  std::pair<int,F> max(const DocumentId& doc) const;
  int max_topic() const;

  void set_backoff(const std::string& filename) {
    m_backoff.reset(new TermBackoff);
    m_backoff->read(filename);
    m_word_pyps.clear();
    m_word_pyps.resize(m_backoff->order(), MPIPYPs());
  }
  void set_backoff(TermBackoffPtr backoff) {
    m_backoff = backoff;
    m_word_pyps.clear();
    m_word_pyps.resize(m_backoff->order(), MPIPYPs());
  }

  F prob(const Term& term, int topic, int level=0) const;
  void decrement(const Term& term, int topic, int level=0);
  void increment(const Term& term, int topic, int level=0);

  std::ostream& print_document_topics(std::ostream& out) const;
  std::ostream& print_topic_terms(std::ostream& out) const;

  void synchronise();

private:
  F word_pyps_p0(const Term& term, int topic, int level) const;

  int m_num_topics;
  F m_term_p0, m_topic_p0, m_backoff_p0;

  CorpusTopics m_corpus_topics;
  typedef boost::ptr_vector< PYP<int> > PYPs;
  typedef boost::ptr_vector< MPIPYP<int> > MPIPYPs;
  PYPs m_document_pyps;
  std::vector<MPIPYPs> m_word_pyps;
  MPIPYP<int> m_topic_pyp;
  bool m_use_topic_pyp;

  unsigned long m_seed;

  //typedef boost::mt19937 base_generator_type;
  //typedef boost::hellekalek1995 base_generator_type;
  typedef boost::lagged_fibonacci607 base_generator_type;
  typedef boost::uniform_real<> uni_dist_type;
  typedef boost::variate_generator<base_generator_type&, uni_dist_type> gen_type;

  uni_dist_type uni_dist;
  base_generator_type rng; //this gets the seed
  gen_type rnd; //instantiate: rnd(rng, uni_dist)
                //call: rnd() generates uniform on [0,1)

  TermBackoffPtr m_backoff;

  boost::mpi::communicator m_world;
  bool m_am_root;
  int m_rank, m_size;
  int m_mpi_start, m_mpi_end;
};

#endif // PYP_TOPICS_HH

ext: hh

max_stars_repo_name: agesmundo/FasterCubePruning

max_issues_repo_name: jhclark/cdec

max_forks_repo_name: jhclark/cdec


text:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/algorithm/iteration/accumulate.hpp>
#include <boost/fusion/include/accumulate.hpp>

#include <iterator>

namespace geiger
{

template <typename... _PAPIWrappersT>
std::vector<std::reference_wrapper<const std::string>> suite<_PAPIWrappersT...>::test_names() const
{
    std::vector<std::reference_wrapper<const std::string>> v;

    for (const auto& test : m_tests)
        v.push_back(test->name());

    return v;
}

#ifdef USE_PAPI

template <typename... _PAPIWrappersT>
std::vector<int> suite<_PAPIWrappersT...>::papi_events() const
{
    std::vector<int> v;
    std::tuple<_PAPIWrappersT...> papi_wrappers;

    boost::fusion::for_each(papi_wrappers, [&v](auto& papi)
                            {
                                for (int event : papi.get_event_types())
                                    v.push_back(event);
                            });

    return v;
}

#endif

template <typename... _PAPIWrappersT>
suite<_PAPIWrappersT...>& suite<_PAPIWrappersT...>::run(std::chrono::milliseconds duration)
{
    return run_impl(duration);
}

template <typename... _PAPIWrappersT>
suite<_PAPIWrappersT...>& suite<_PAPIWrappersT...>::run(long iterations)
{
    return run_impl(iterations);
}

template <typename... _PAPIWrappersT>
template <typename _DurationT>
suite<_PAPIWrappersT...>& suite<_PAPIWrappersT...>::run_impl(_DurationT duration)
{
    suite_report r;

    if (m_printer)
        m_printer->on_start(*this);

    for (const auto& p : m_tests)
    {
        test_report test_report = p->run(duration);
        r.tests.emplace_back(p->name(), test_report);

        if (m_on_test_complete)
            m_on_test_complete(p->name(), test_report);

        if (m_printer)
            m_printer->on_test_complete(p->name(), test_report);
    }

    if (m_on_complete)
        m_on_complete(r);

    return *this;
}

template <typename _CallableT, typename... _PAPIWrappersT>
test_report test<_CallableT, _PAPIWrappersT...>::run(std::chrono::milliseconds duration) const
{
    test_report r = run(1);

    assert((r.iteration_count() == 1 && sizeof...(_PAPIWrappersT) == 0)
           || r.iteration_count() == sizeof...(_PAPIWrappersT));

    auto time_elapsed = r.time_per_task();
    if (time_elapsed > duration)
        return r;

    long iterations = duration / time_elapsed;
    return run(iterations, std::chrono::nanoseconds(duration));
}

template <typename _CallableT, typename... _PAPIWrappersT>
test_report test<_CallableT, _PAPIWrappersT...>::run(long iterations,
                                                     boost::optional<std::chrono::nanoseconds> duration) const
{
    long batches;

    if (!duration)
    {
        batches = 1;
    }
    else
    {
        // TODO
        if (iterations > 1e6)
            batches = 1e3;
        else if (iterations > 1e4)
            batches = 100;
        else if (iterations > 1e3)
            batches = 10;
        else
            batches = 1;
    }

    iterations /= batches;
    chrono c;

    auto run_benchmark = [&]() -> auto
    {
        c.start();

        for (long i = 0; i < iterations; ++i)
            m_callable();

        return c.elapsed();
    };

    auto next_iterations_count = [&](int64_t cycles_last_batch)
    {
        if (duration)
        {
            int64_t expected_cycles = chrono::to_cycles(duration.get() / batches);
            double calibration = cycles_last_batch / (double)expected_cycles;

            iterations = std::lround(iterations / calibration);
        }
    };

    constexpr long papi_wrapppers_count = sizeof...(_PAPIWrappersT);

    int64_t total_cycles = 0;
    long total_iterations = 0;

#ifndef USE_PAPI
    static_assert(papi_wrapppers_count == 0, "PAPI not supported");
#endif

#ifdef USE_PAPI
    if (papi_wrapppers_count == 0)
    {
#endif
        for (int i = 0; i < batches; ++i)
        {
            int64_t cycles = run_benchmark();

            total_iterations += iterations;
            total_cycles += cycles;
            next_iterations_count(cycles);
        }

        return {total_iterations, total_cycles};
#ifdef USE_PAPI
    }

    std::tuple<_PAPIWrappersT...> papi_wrappers;
    int hwd_counters = boost::fusion::accumulate(papi_wrappers, 0, [&](int count, auto& papi) { return count + papi.events_count; });

    std::vector<long long> counters;
    counters.reserve(hwd_counters);

    boost::fusion::for_each(papi_wrappers, [&](auto& papi)
                            {
                                std::vector<long long> curr_counters(papi.events_count);

                                for (int i = 0; i < batches; ++i)
                                {
                                    papi.start();
                                    int64_t cycles = run_benchmark();
                                    papi.stop();

                                    total_iterations += iterations;
                                    total_cycles += cycles;
                                    next_iterations_count(cycles);

                                    const auto& batch_counters = papi.get_counters();

                                    for (int j = 0; j < (int)curr_counters.size(); ++j)
                                        curr_counters[j] += batch_counters[j];
                                }

                                std::copy(curr_counters.begin(),
                                          curr_counters.end(),
                                          std::back_inserter(counters));
                            });

    return {total_iterations, total_cycles, std::move(counters)};

#endif
}

}

ext: tcc

max_stars_repo_name: david-grs/disco

max_issues_repo_name: Icefishc/geiger

max_forks_repo_name: Icefishc/geiger


text:
#define BOOST_TEST_MODULE TestClFFT

#include "libraries/clfft/clfft_helper.hpp"
#include <boost/test/unit_test.hpp>
#include <boost/mpl/list.hpp>

using test_types = boost::mpl::list<float, double>;

template< typename TPrecision=float >
struct FFTPrecision: std::integral_constant< clfftPrecision, CLFFT_SINGLE >{};
template<>
struct FFTPrecision<double>: std::integral_constant< clfftPrecision, CLFFT_DOUBLE >{};

using namespace gearshifft::ClFFT;

BOOST_AUTO_TEST_CASE( CL_Context_CPU )
{
  cl_device_id device = 0;
  cl_context ctx = 0;
  cl_platform_id platform=0;
  cl_int err = CL_SUCCESS;
  try{
    findClDevice(CL_DEVICE_TYPE_CPU, &platform, &device);
    ctx = clCreateContext( NULL, 1, &device, NULL, NULL, &err );
    CHECK_CL(err);
    BOOST_REQUIRE( err==CL_SUCCESS );
    CHECK_CL(clReleaseContext( ctx ));
    CHECK_CL(clReleaseDevice(device));
  }catch(std::runtime_error& e){
    BOOST_REQUIRE_MESSAGE(err == CL_SUCCESS, "failed with error: " << e.what());
  }
}

BOOST_AUTO_TEST_CASE( CL_Context_GPU )
{
  cl_device_id device = 0;
  cl_context ctx = 0;
  cl_platform_id platform=0;
  cl_int err = CL_SUCCESS;
  try{
    findClDevice(CL_DEVICE_TYPE_GPU, &platform, &device);
    ctx = clCreateContext( NULL, 1, &device, NULL, NULL, &err );
    CHECK_CL(err);
    BOOST_REQUIRE( err==CL_SUCCESS );
    CHECK_CL(clReleaseContext( ctx ));
    CHECK_CL(clReleaseDevice(device));
  }catch(std::runtime_error& e){
    BOOST_REQUIRE_MESSAGE(err == CL_SUCCESS, "failed with error: " << e.what());
  }
}

BOOST_AUTO_TEST_CASE( CLFFT_2D_C2C )
{
  cl_int err = CL_SUCCESS;
  cl_platform_id platform = 0;
  cl_device_id device = 0;
  cl_context_properties props[3] = { CL_CONTEXT_PLATFORM, 0, 0 };
  cl_context ctx = 0;
  cl_command_queue queue = 0;
  cl_mem bufX;
  float *X;
  cl_event event = NULL;
  int ret = 0;

  const size_t N0 = 1024, N1 = 8192;
  char platform_name[128];
  char device_name[128];

  /* FFT library realted declarations */
  clfftPlanHandle planHandle;
  clfftDim dim = CLFFT_2D;
  size_t clLengths[2] = {N0, N1};

  /* Setup OpenCL environment. */
  err |= clGetPlatformIDs( 1, &platform, NULL );

  size_t ret_param_size = 0;
  err |= clGetPlatformInfo(platform, CL_PLATFORM_NAME,
                          sizeof(platform_name), platform_name,
                          &ret_param_size);

  err |= clGetDeviceIDs( platform, CL_DEVICE_TYPE_DEFAULT, 1, &device, NULL );

  err |= clGetDeviceInfo(device, CL_DEVICE_NAME,
                        sizeof(device_name), device_name,
                        &ret_param_size);

  props[1] = (cl_context_properties)platform;
  ctx = clCreateContext( props, 1, &device, NULL, NULL, &err );
  queue = clCreateCommandQueue( ctx, device, 0, &err );

  clfftSetupData fftSetup;
  err |= clfftInitSetupData(&fftSetup);
  err |= clfftSetup(&fftSetup);

  size_t buffer_size  = N0 * N1 * 2 * sizeof(*X);
  X = (float *)malloc(buffer_size);

  size_t i, j;
  i = j = 0;
  for (i=0; i<N0; ++i) {
    for (j=0; j<N1; ++j) {
      size_t idx = 2*(j+i*N1);
      X[idx] = 0.5f;
      X[idx+1] = 0.5f;
    }
  }

  bufX = clCreateBuffer( ctx, CL_MEM_READ_WRITE, buffer_size, NULL, &err );
  err |= clEnqueueWriteBuffer( queue, bufX, CL_TRUE, 0, buffer_size, X, 0, NULL, NULL );

  err |= clfftCreateDefaultPlan(&planHandle, ctx, dim, clLengths);
  err |= clfftSetPlanPrecision(planHandle, CLFFT_SINGLE);
  err |= clfftSetLayout(planHandle, CLFFT_COMPLEX_INTERLEAVED, CLFFT_COMPLEX_INTERLEAVED);
  err |= clfftSetResultLocation(planHandle, CLFFT_INPLACE);
  err |= clfftBakePlan(planHandle, 1, &queue, NULL, NULL);

  err |= clfftEnqueueTransform(planHandle, CLFFT_FORWARD, 1, &queue, 0, NULL, NULL, &bufX, NULL, NULL);
  err |= clFinish(queue);

  err |= clEnqueueReadBuffer( queue, bufX, CL_TRUE, 0, buffer_size, X, 0, NULL, NULL );

  clReleaseMemObject( bufX );
  free(X);

  err |= clfftDestroyPlan( &planHandle );

  clfftTeardown( );

  clReleaseCommandQueue( queue );
  clReleaseContext( ctx );
  BOOST_CHECK( err == CL_SUCCESS );
}

BOOST_AUTO_TEST_CASE_TEMPLATE( CLFFT_1D_R2C_INPLACE, T, test_types )
{
  cl_int err = CL_SUCCESS;
  cl_platform_id platform = 0;
  cl_device_id device = 0;
  cl_context ctx = 0;
  cl_command_queue queue = 0;
  cl_mem bufX;
  T *X = NULL;
  cl_event event = NULL;
  int ret = 0;

  size_t N = 2048;

  clfftPlanHandle planHandle;
  clfftDim dim = CLFFT_1D;

  size_t clLengths[1] = {N};
  size_t strides[3] = {1};
  size_t strides_complex[3] = {1};
  size_t dist;
  size_t dist_complex = 1;

  size_t bytes_r = N * sizeof(T);
  size_t bytes_c = (N/2+1) * 2 * sizeof(T);

  findClDevice(CL_DEVICE_TYPE_DEFAULT, &platform, &device);
  ctx = clCreateContext( NULL, 1, &device, NULL, NULL, &err );
  CHECK_CL( err );
  queue = clCreateCommandQueue( ctx, device, 0, &err );
  CHECK_CL( err );

  clfftSetupData fftSetup;
  CHECK_CL( clfftInitSetupData(&fftSetup) );
  CHECK_CL( clfftSetup(&fftSetup) );

  dist = 2 * (N/2 + 1);
  dist_complex = N/2+1;

  X = new T[dist];
  for(int k=0; k<dist; ++k)
    X[k] = 1.0;

  bufX = clCreateBuffer( ctx, CL_MEM_READ_WRITE, bytes_c, NULL, &err );
  CHECK_CL( err );
  CHECK_CL( clEnqueueWriteBuffer( queue, bufX, CL_TRUE, 0,
                                  bytes_r, X, 0, NULL, NULL ) );

  CHECK_CL( clfftCreateDefaultPlan(&planHandle, ctx, dim, clLengths) );

  CHECK_CL( clfftSetPlanPrecision(planHandle, FFTPrecision<T>::value) );
  CHECK_CL( clfftSetLayout(planHandle, CLFFT_REAL, CLFFT_HERMITIAN_INTERLEAVED) );
  CHECK_CL( clfftSetResultLocation(planHandle, CLFFT_INPLACE) );

  CHECK_CL(clfftSetPlanInStride(planHandle, dim, strides));
  CHECK_CL(clfftSetPlanOutStride(planHandle, dim, strides_complex));
  CHECK_CL(clfftSetPlanDistance(planHandle, dist, dist_complex));

  CHECK_CL( clfftBakePlan(planHandle, 1, &queue, NULL, NULL) );

  CHECK_CL( clfftEnqueueTransform(planHandle, CLFFT_FORWARD, 1, &queue, 0, NULL, NULL, &bufX, NULL, NULL) );
  CHECK_CL( clFinish(queue) );

  CHECK_CL( clfftDestroyPlan( &planHandle ) );

  CHECK_CL( clfftCreateDefaultPlan(&planHandle, ctx, dim, clLengths) );
  CHECK_CL( clfftSetPlanPrecision(planHandle, FFTPrecision<T>::value) );
  CHECK_CL( clfftSetLayout(planHandle, CLFFT_HERMITIAN_INTERLEAVED, CLFFT_REAL) );
  CHECK_CL( clfftSetResultLocation(planHandle, CLFFT_INPLACE) );
  CHECK_CL(clfftSetPlanInStride(planHandle, dim, strides_complex));
  CHECK_CL(clfftSetPlanOutStride(planHandle, dim, strides));
  CHECK_CL(clfftSetPlanDistance(planHandle, dist_complex, dist));
  CHECK_CL( clfftBakePlan(planHandle, 1, &queue, NULL, NULL) );

  CHECK_CL( clfftEnqueueTransform(planHandle, CLFFT_BACKWARD, 1, &queue, 0, NULL, NULL, &bufX, NULL, NULL) );
  CHECK_CL( clFinish(queue) );

  CHECK_CL( clEnqueueReadBuffer( queue, bufX, CL_TRUE, 0, bytes_r, X, 0, NULL, NULL ) );

  CHECK_CL( clReleaseMemObject( bufX ) );

  //CHECK_CL( clfftDestroyPlan( &planHandle ) );
  CHECK_CL( clfftDestroyPlan( &planHandle ) );
  CHECK_CL( clfftTeardown() );
  CHECK_CL( clReleaseCommandQueue( queue ) );
  CHECK_CL( clReleaseContext( ctx ) );

  for(int k=0; k<dist; ++k)
    BOOST_TEST(X[k] == 1.0, boost::test_tools::tolerance(0.0001f));

  delete[] X;
}

ext: cpp

max_stars_repo_name: psteinb/gearshifft

max_issues_repo_name: psteinb/gearshifft

max_forks_repo_name: psteinb/gearshifft


text:
/*
// Copyright 2018 University of Liege
//
// 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.
//
// Authors:
// - Adrien Crovato
*/

//// Interpolation from center to vertices
// Interpolate linearly surface singularities from adjacent panel centers to panel vertices. If panel is on an edge of a
// network, linear extrapolation is used instead
//
// Inputs:
// - idG: current panel global index
// - idC: current panel chordwise index
// - idS: current panel spanwise index
// - bPan: body panels (structure)
//
// Output:
// - vis: Matrix of interpolate singularities (row = vertex number; col 0 = doublet, col 1 = source)

#include <iostream>
#include <Eigen/Dense>
#include "interp_ctv.h"
#include <interp.h>

#define NDIM 3
#define NV 4

using namespace std;
using namespace Eigen;

MatrixXd interp_ctv(int idG, int idC, int idS, Network &bPan) {

    //// Initialization
    // Temporary
    MatrixXd v; // vertices coordinates
    v.resize(NV, NDIM);
    MatrixXi c; // centers (corner of interpolation)
    c.resize(NV, 4);
    MatrixXd vis; // interpolated singularities on vertices
    vis.resize(NV, 2);

    // Store vertices coordinates
    v.row(0) = bPan.v0.row(idG);
    v.row(1) = bPan.v1.row(idG);
    v.row(2) = bPan.v2.row(idG);
    v.row(3) = bPan.v3.row(idG);

    //// Compute panel center indices
    // If panel is on the last row/column, linear extrapolation is used
    if (idS == 0) {
        if (idC == 0) {
            c(0,0) = idG;
            c(0,1) = idG + 1;
            c(0,2) = idG + 1 + bPan.nC_;
            c(0,3) = idG + bPan.nC_;
            c(1,0) = idG;
            c(1,1) = idG + 1;
            c(1,2) = idG + 1 + bPan.nC_;
            c(1,3) = idG + bPan.nC_;
            c(2,0) = idG;
            c(2,1) = idG + 1;
            c(2,2) = idG + 1 + bPan.nC_;
            c(2,3) = idG + bPan.nC_;
            c(3,0) = idG;
            c(3,1) = idG + 1;
            c(3,2) = idG + 1 + bPan.nC_;
            c(3,3) = idG + bPan.nC_;
        }
        else if (idC == bPan.nC_ - 1) {
            c(0,0) = idG - 1;
            c(0,1) = idG;
            c(0,2) = idG + bPan.nC_;
            c(0,3) = idG - 1 + bPan.nC_;
            c(1,0) = idG - 1;
            c(1,1) = idG;
            c(1,2) = idG + bPan.nC_;
            c(1,3) = idG - 1 + bPan.nC_;
            c(2,0) = idG - 1;
            c(2,1) = idG;
            c(2,2) = idG + bPan.nC_;
            c(2,3) = idG - 1 + bPan.nC_;
            c(3,0) = idG - 1;
            c(3,1) = idG;
            c(3,2) = idG + bPan.nC_;
            c(3,3) = idG - 1 + bPan.nC_;
        }
        else {
            c(0,0) = idG - 1;
            c(0,1) = idG;
            c(0,2) = idG + bPan.nC_;
            c(0,3) = idG - 1 + bPan.nC_;
            c(1,0) = idG;
            c(1,1) = idG + 1;
            c(1,2) = idG + 1 + bPan.nC_;
            c(1,3) = idG + bPan.nC_;
            c(2,0) = idG;
            c(2,1) = idG + 1;
            c(2,2) = idG + 1 + bPan.nC_;
            c(2,3) = idG + bPan.nC_;
            c(3,0) = idG - 1;
            c(3,1) = idG;
            c(3,2) = idG + bPan.nC_;
            c(3,3) = idG - 1 + bPan.nC_;
        }
    }
    else if (idS == bPan.nS_ - 1) {
        if (idC == 0) {
            c(0,0) = idG - bPan.nC_;
            c(0,1) = idG - bPan.nC_ + 1;
            c(0,2) = idG + 1;
            c(0,3) = idG;
            c(1,0) = idG - bPan.nC_;
            c(1,1) = idG - bPan.nC_ + 1;
            c(1,2) = idG + 1;
            c(1,3) = idG;
            c(2,0) = idG - bPan.nC_;
            c(2,1) = idG - bPan.nC_ + 1;
            c(2,2) = idG + 1;
            c(2,3) = idG;
            c(3,0) = idG - bPan.nC_;
            c(3,1) = idG - bPan.nC_ + 1;
            c(3,2) = idG + 1;
            c(3,3) = idG;
        }
        else if (idC == bPan.nC_ - 1) {
            c(0,0) = idG - 1 - bPan.nC_;
            c(0,1) = idG - bPan.nC_;
            c(0,2) = idG;
            c(0,3) = idG - 1;
            c(1,0) = idG - 1 - bPan.nC_;
            c(1,1) = idG - bPan.nC_;
            c(1,2) = idG;
            c(1,3) = idG - 1;
            c(2,0) = idG - 1 - bPan.nC_;
            c(2,1) = idG - bPan.nC_;
            c(2,2) = idG;
            c(2,3) = idG - 1;
            c(3,0) = idG - 1 - bPan.nC_;
            c(3,1) = idG - bPan.nC_;
            c(3,2) = idG;
            c(3,3) = idG - 1;
        }
        else {
            c(0,0) = idG - 1 - bPan.nC_;
            c(0,1) = idG - bPan.nC_;
            c(0,2) = idG;
            c(0,3) = idG - 1;
            c(1,0) = idG - bPan.nC_;
            c(1,1) = idG - bPan.nC_ + 1;
            c(1,2) = idG + 1;
            c(1,3) = idG;
            c(2,0) = idG - bPan.nC_;
            c(2,1) = idG - bPan.nC_ + 1;
            c(2,2) = idG + 1;
            c(2,3) = idG;
            c(3,0) = idG - 1 - bPan.nC_;
            c(3,1) = idG - bPan.nC_;
            c(3,2) = idG;
            c(3,3) = idG - 1;
        }
    }
    else {
        c(0,0) = idG - 1 - bPan.nC_;
        c(0,1) = idG - bPan.nC_;
        c(0,2) = idG;
        c(0,3) = idG - 1;
        c(1,0) = idG - bPan.nC_;
        c(1,1) = idG - bPan.nC_ + 1;
        c(1,2) = idG + 1;
        c(1,3) = idG;
        c(2,0) = idG;
        c(2,1) = idG + 1;
        c(2,2) = idG + 1 + bPan.nC_;
        c(2,3) = idG + bPan.nC_;
        c(3,0) = idG - 1;
        c(3,1) = idG;
        c(3,2) = idG + bPan.nC_;
        c(3,3) = idG - 1 + bPan.nC_;
    }

    //// Interpolate each vertex
    for (int l = 0; l < NV; l++) {
        vis(l,0) = interp(bPan.CG(c(l,0),0), bPan.CG(c(l,0),1), bPan.CG(c(l,0),2),
                          bPan.CG(c(l,1),0), bPan.CG(c(l,1),1), bPan.CG(c(l,1),2),
                          bPan.CG(c(l,2),0), bPan.CG(c(l,2),1), bPan.CG(c(l,2),2),
                          bPan.CG(c(l,3),0), bPan.CG(c(l,3),1), bPan.CG(c(l,3),2),
                          bPan.mu(c(l,0)), bPan.mu(c(l,1)), bPan.mu(c(l,2)), bPan.mu(c(l,3)),
                          v(l,0), v(l,1), v(l,2));

        vis(l,1) = interp(bPan.CG(c(l,0),0), bPan.CG(c(l,0),1), bPan.CG(c(l,0),2),
                          bPan.CG(c(l,1),0), bPan.CG(c(l,1),1), bPan.CG(c(l,1),2),
                          bPan.CG(c(l,2),0), bPan.CG(c(l,2),1), bPan.CG(c(l,2),2),
                          bPan.CG(c(l,3),0), bPan.CG(c(l,3),1), bPan.CG(c(l,3),2),
                          bPan.tau(c(l,0)), bPan.tau(c(l,1)), bPan.tau(c(l,2)), bPan.tau(c(l,3)),
                          v(l,0), v(l,1), v(l,2));
    }
    return vis;
}

max_stars_repo_name: acrovato/aero

max_issues_repo_name: acrovato/aero

max_forks_repo_name: acrovato/aero