text:
/*
 * Copyright 2020 OmniSci, Inc.
 *
 * 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 "TestHelpers.h"

#include <gtest/gtest.h>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>
#include <limits>
#include <string>

#include "Archive/PosixFileArchive.h"
#include "Catalog/Catalog.h"
#include "DataMgr/ForeignStorage/ArrowCsvForeignStorage.h"
#include "Import/Importer.h"
#include "Parser/parser.h"
#include "QueryEngine/ResultSet.h"
#include "QueryRunner/QueryRunner.h"
#include "Shared/geo_types.h"
#include "Shared/scope.h"

#ifndef BASE_PATH
#define BASE_PATH "./tmp"
#endif

using namespace std;
using namespace TestHelpers;
using QR = QueryRunner::QueryRunner;

extern bool g_use_date_in_days_default_encoding;

namespace {

inline void run_ddl_statement(const string& input_str) {
  QR::get()->runDDLStatement(input_str);
}

TargetValue run_simple_agg(const string& query_str) {
  auto rows = QR::get()->runSQL(query_str, ExecutorDeviceType::CPU, false);
  auto crt_row = rows->getNextRow(true, true);
  CHECK_EQ(size_t(1), crt_row.size()) << query_str;
  return crt_row[0];
}

template <typename T>
void check_query(const std::string& query, const std::vector<T>& expects) {
  auto rows = QR::get()->runSQL(query, ExecutorDeviceType::CPU, false);
  CHECK_EQ(expects.size(), rows->rowCount());
  for (auto exp : expects) {
    auto crt_row = rows->getNextRow(true, true);
    CHECK_EQ(size_t(1), crt_row.size());
    CHECK_EQ(exp, v<T>(crt_row[0]));
  }
}

const char* trips_table_ddl = R"(
CREATE TEMPORARY TABLE trips (
trip_id BIGINT,
vendor_id TEXT ENCODING NONE,
pickup_datetime TIMESTAMP,
dropoff_datetime TIMESTAMP,
store_and_fwd_flag TEXT ENCODING DICT,
rate_code_id BIGINT,
pickup_longitude DOUBLE,
pickup_latitude DOUBLE,
dropoff_longitude DOUBLE,
dropoff_latitude DOUBLE,
passenger_count BIGINT,
trip_distance DOUBLE,
fare_amount DOUBLE,
extra DOUBLE,
mta_tax DOUBLE,
tip_amount DOUBLE,
tolls_amount DOUBLE,
ehail_fee DOUBLE,
improvement_surcharge DOUBLE,
total_amount DOUBLE,
payment_type TEXT ENCODING DICT,
trip_type BIGINT,
pickup TEXT ENCODING DICT,
dropoff TEXT ENCODING NONE,
cab_type TEXT ENCODING DICT,
precipitation DOUBLE,
snow_depth BIGINT,
snowfall DOUBLE,
max_temperature BIGINT,
min_temperature BIGINT,
average_wind_speed DOUBLE,
pickup_nyct2010_gid BIGINT,
pickup_ctlabel DOUBLE,
pickup_borocode BIGINT,
pickup_boroname TEXT ENCODING NONE,
pickup_ct2010 BIGINT,
pickup_boroct2010 BIGINT,
pickup_cdeligibil TEXT ENCODING DICT,
pickup_ntacode TEXT ENCODING DICT,
pickup_ntaname TEXT ENCODING DICT,
pickup_puma BIGINT,
dropoff_nyct2010_gid BIGINT,
dropoff_ctlabel DOUBLE,
dropoff_borocode BIGINT,
dropoff_boroname TEXT ENCODING NONE,
dropoff_ct2010 BIGINT,
dropoff_boroct2010 BIGINT,
dropoff_cdeligibil TEXT ENCODING NONE,
dropoff_ntacode TEXT ENCODING NONE,
dropoff_ntaname TEXT ENCODING NONE,
dropoff_puma BIGINT) WITH (storage_type='CSV:../../Tests/Import/datafiles/trips_with_headers_top1000.csv');
)";

class NycTaxiTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ASSERT_NO_THROW(run_ddl_statement("drop table if exists trips;"););
    ASSERT_NO_THROW(run_ddl_statement(trips_table_ddl));
  }

  void TearDown() override {
    ASSERT_NO_THROW(run_ddl_statement("drop table if exists trips;"););
  }
};

TEST_F(NycTaxiTest, RunSimpleQuery) {
  // TODO: expect +1 rows when move to arrow 0.15 as current arrow doesn't support
  // headerless csv
  ASSERT_EQ(999,
            v<int64_t>(run_simple_agg(
                "SELECT count(vendor_id) FROM trips where vendor_id < '5'")));
}

TEST_F(NycTaxiTest, GroupByColumnWithNulls) {
  // TODO: expect +1 rows when move to arrow 0.15 as current arrow doesn't support
  // headerless csv
  ASSERT_EQ(
      619,
      v<int64_t>(run_simple_agg(
          " select count(*) from (select pickup, count(*) from trips group by pickup)")));
}

TEST_F(NycTaxiTest, CheckGroupBy) {
  check_query<NullableString>(
      "select pickup_ntaname from trips where pickup_ntaname IS NOT NULL group by "
      "pickup_ntaname limit 5;",
      {"Queensbridge-Ravenswood-Long Island City",
       "Steinway",
       "Claremont-Bathgate",
       "Washington Heights South",
       "Spuyten Duyvil-Kingsbridge"});

  check_query<double>("select tip_amount from trips group by tip_amount limit 5;",
                      {0.47, 0.05, 3.96, 5, 1.22});

  check_query<NullableString>(
      "select store_and_fwd_flag from trips group by store_and_fwd_flag limit 5;",
      {"N", "Y"});
}

TEST_F(NycTaxiTest, RunSelects) {
  check_query<int64_t>("select rate_code_id from trips limit 5;", {1, 1, 5, 1, 1});
}

TEST_F(NycTaxiTest, RunSelectsEncodingNoneNotNull) {
  check_query<NullableString>(
      "select dropoff_ntaname from trips where dropoff_ntaname is not NULL limit 10 "
      "offset 100;",
      {"Queensbridge-Ravenswood-Long Island City",
       "Queensbridge-Ravenswood-Long Island City",
       "West Village",
       "Hunters Point-Sunnyside-West Maspeth",
       "Hunters Point-Sunnyside-West Maspeth",
       "Hunters Point-Sunnyside-West Maspeth",
       "Hunters Point-Sunnyside-West Maspeth",
       "Manhattanville",
       "Central Harlem South",
       "Washington Heights South"});
}

TEST_F(NycTaxiTest, RunSelectsEncodingNoneWhereGreater) {
  check_query<NullableString>(
      "select dropoff_ntaname from trips where dropoff_ntaname > "
      "'Queensbridge-Ravenswood-Long Island City' limit 3 offset 100;",
      {"Woodside", "park-cemetery-etc-Manhattan", "West Concourse"});
}

TEST_F(NycTaxiTest, RunSelectsEncodingDictWhereGreater) {
  check_query<NullableString>(
      "select pickup_ntaname from trips where pickup_ntaname is not NULL and "
      "pickup_ntaname > 'Queensbridge-Ravenswood-Long Island City' limit 3 offset 100;",
      {"West Farms-Bronx River", "Washington Heights South", "Steinway"});
}

TEST(Unsupported, Syntax) {
  run_ddl_statement("DROP TABLE IF EXISTS fsi_unsupported;");
  EXPECT_ANY_THROW(
      run_ddl_statement("CREATE TABLE fsi_unsupported (x INT, y DOUBLE) WITH "
                        "(storage_type='CSV:../../Tests/Import/datafiles/"
                        "trips_with_headers_top1000.csv');"));
}

}  // namespace

int main(int argc, char** argv) {
  testing::InitGoogleTest(&argc, argv);

  namespace po = boost::program_options;

  po::options_description desc("Options");

  // these two are here to allow passing correctly google testing parameters
  desc.add_options()("gtest_list_tests", "list all tests");
  desc.add_options()("gtest_filter", "filters tests, use --help for details");

  desc.add_options()("test-help",
                     "Print all ArrowCsvForeighStorageTest specific options (for gtest "
                     "options use `--help`).");

  logger::LogOptions log_options(argv[0]);
  log_options.max_files_ = 0;  // stderr only by default
  desc.add(log_options.get_options());

  po::variables_map vm;
  po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
  po::notify(vm);

  if (vm.count("test-help")) {
    std::cout << "Usage: ArrowCsvForeighStorageTest" << std::endl << std::endl;
    std::cout << desc << std::endl;
    return 0;
  }

  logger::init(log_options);

  QR::init(BASE_PATH);
  registerArrowCsvForeignStorage();
  int err{0};
  try {
    err = RUN_ALL_TESTS();
  } catch (const std::exception& e) {
    LOG(ERROR) << e.what();
  }
  QR::reset();
  return err;
}

max_stars_repo_name: dr-pain/omniscidb

max_issues_repo_name: dr-pain/omniscidb

max_forks_repo_name: dr-pain/omniscidb


text:
#include "rbfcore.h"
#include "utility.h"
#include "Solver.h"
#include <armadillo>
#include <fstream>
#include <limits>
#include <iomanip>
#include <ctime>
#include <chrono>
#include<algorithm>

double sigma = 2.0;
double inv_sigma_squarex2 = 1/(2 * pow(sigma, 2));
double Gaussian_Kernel(const double x_square){

    return exp(-x_square*inv_sigma_squarex2);

}

double Gaussian_Kernel_2p(const double *p1, const double *p2){

    return Gaussian_Kernel(MyUtility::vecSquareDist(p1,p2));

}

double Gaussian_PKernel_Dirichlet_2p(const double *p1, const double *p2){

    double d2 = MyUtility::vecSquareDist(p1,p2);
    return (6*sigma*sigma-d2)*sqrt(Gaussian_Kernel(d2));

}

double Gaussian_PKernel_Bending_2p(const double *p1, const double *p2){

    double d2 = MyUtility::vecSquareDist(p1,p2);
    double d4 = d2*d2;
    double sigma2 = sigma * sigma;
    double sigma4 = sigma2 * sigma2;
    return (60*sigma4-20*sigma2*d2+d4)*sqrt(Gaussian_Kernel(d2));

}

double XCube_Kernel(const double x){

    return pow(x,3);
}

double XCube_Kernel_2p(const double *p1, const double *p2){

    return XCube_Kernel(MyUtility::_VerticesDistance(p1,p2));

}

void XCube_Gradient_Kernel_2p(const double *p1, const double *p2, double *G){

    double len_dist  = MyUtility::_VerticesDistance(p1,p2);
    for(int i=0;i<3;++i)G[i] = 3*len_dist*(p1[i]-p2[i]);
    return;

}

double XCube_GradientDot_Kernel_2p(const double *p1, const double *p2, const double *p3){

    double G[3];
    XCube_Gradient_Kernel_2p(p1,p2,G);
    return MyUtility::dot(p3,G);

}

void XCube_Hessian_Kernel_2p(const double *p1, const double *p2, double *H){

    double diff[3];
    for(int i=0;i<3;++i)diff[i] = p1[i] - p2[i];
    double len_dist  = sqrt(MyUtility::len(diff));

    if(len_dist<1e-8){
        for(int i=0;i<9;++i)H[i] = 0;
    }else{
        for(int i=0;i<3;++i)for(int j=0;j<3;++j)
            if(i==j)H[i*3+j] = 3 * pow(diff[i],2) / len_dist + 3 * len_dist;
            else H[i*3+j] = 3 * diff[i] * diff[j] / len_dist;
    }

    return;

}

void XCube_HessianDot_Kernel_2p(const double *p1, const double *p2, const double *p3, vector<double>&dotout){

    double H[9];
    XCube_Gradient_Kernel_2p(p1,p2,H);
    dotout.resize(3);
    for(int i=0;i<3;++i){
        dotout[i] = 0;
        for(int j=0;j<3;++j){
            dotout[i] += H[i*3+j] * p3[j];
        }
    }

}

RBF_Core::RBF_Core(){

    Kernal_Function = Gaussian_Kernel;
    Kernal_Function_2p = Gaussian_Kernel_2p;
    P_Function_2p = Gaussian_PKernel_Dirichlet_2p;

    isHermite = false;

    mp_RBF_INITMETHOD.insert(make_pair(GT_NORMAL,"GT_NORMAL"));
    mp_RBF_INITMETHOD.insert(make_pair(GlobalEigen,"GlobalEigen"));
    mp_RBF_INITMETHOD.insert(make_pair(GlobalEigenWithMST,"GlobalEigenWithMST"));
    mp_RBF_INITMETHOD.insert(make_pair(GlobalEigenWithGT,"GlobalEigenWithGT"));
    mp_RBF_INITMETHOD.insert(make_pair(LocalEigen,"LocalEigen"));
    mp_RBF_INITMETHOD.insert(make_pair(IterativeEigen,"IterativeEigen"));
    mp_RBF_INITMETHOD.insert(make_pair(ClusterEigen,"ClusterEigen"));

    mp_RBF_METHOD.insert(make_pair(Variational,"Variational"));
    mp_RBF_METHOD.insert(make_pair(Variational_P,"Variation_P"));
    mp_RBF_METHOD.insert(make_pair(LS,"LS"));
    mp_RBF_METHOD.insert(make_pair(LSinterp,"LSinterp"));
    mp_RBF_METHOD.insert(make_pair(Interp,"Interp"));
    mp_RBF_METHOD.insert(make_pair(RayleighQuotients,"Rayleigh"));
    mp_RBF_METHOD.insert(make_pair(RayleighQuotients_P,"Rayleigh_P"));
    mp_RBF_METHOD.insert(make_pair(RayleighQuotients_I,"Rayleigh_I"));
    mp_RBF_METHOD.insert(make_pair(Hermite,"Hermite"));
    mp_RBF_METHOD.insert(make_pair(Hermite_UnitNorm,"UnitNorm"));
    mp_RBF_METHOD.insert(make_pair(Hermite_UnitNormal,"UnitNormal"));
    mp_RBF_METHOD.insert(make_pair(Hermite_Tangent_UnitNorm,"T_UnitNorm"));
    mp_RBF_METHOD.insert(make_pair(Hermite_Tangent_UnitNormal,"T_UnitNormal"));

    mp_RBF_Kernal.insert(make_pair(XCube,"TriH"));
    mp_RBF_Kernal.insert(make_pair(ThinSpline,"ThinSpline"));
    mp_RBF_Kernal.insert(make_pair(XLinear,"XLinear"));
    mp_RBF_Kernal.insert(make_pair(Gaussian,"Gaussian"));

}
RBF_Core::RBF_Core(RBF_Kernal kernal){
    isHermite = false;
    Init(kernal);
}

void RBF_Core::Init(RBF_Kernal kernal){

    this->kernal = kernal;
    switch(kernal){
    case Gaussian:
        Kernal_Function = Gaussian_Kernel;
        Kernal_Function_2p = Gaussian_Kernel_2p;
        P_Function_2p = Gaussian_PKernel_Dirichlet_2p;
        break;

    case XCube:
        Kernal_Function = XCube_Kernel;
        Kernal_Function_2p = XCube_Kernel_2p;
        Kernal_Gradient_Function_2p = XCube_Gradient_Kernel_2p;
        Kernal_Hessian_Function_2p = XCube_Hessian_Kernel_2p;
        break;

    default:
        break;

    }

}

void RBF_Core::SetSigma(double x){
    sigma = x;
    inv_sigma_squarex2 = 1/(2 * pow(sigma, 2));
}

double RBF_Core::Dist_Function(const double x, const double y, const double z){

	return -1;

}

inline double RBF_Core::Dist_Function(const double *p){

    n_evacalls++;
    double *p_pts = pts.data();
    static arma::vec kern(npt), kb;
    if(isHermite){
        kern.set_size(npt*4);
        double G[3];
        for(int i=0;i<npt;++i)kern(i) = Kernal_Function_2p(p_pts+i*3, p);
        for(int i=0;i<npt;++i){
            Kernal_Gradient_Function_2p(p,p_pts+i*3,G);
            //for(int j=0;j<3;++j)kern(npt+i*3+j) = -G[j];
            for(int j=0;j<3;++j)kern(npt+i+j*npt) = G[j];
        }
    }else{
        kern.set_size(npt);
        for(int i=0;i<npt;++i)kern(i) = Kernal_Function_2p(p_pts+i*3, p);
    }

    double loc_part = dot(kern,a);

    if(polyDeg==1){
        kb.set_size(4);
        for(int i=0;i<3;++i)kb(i+1) = p[i];
        kb(0) = 1;
    }else if(polyDeg==2){
        vector<double>buf(4,1);
        int ind = 0;
        kb.set_size(10);
        for(int j=0;j<3;++j)buf[j+1] = p[j];
        for(int j=0;j<4;++j)for(int k=j;k<4;++k)kb(ind++) = buf[j] * buf[k];
    }
    double poly_part = dot(kb,b);

    if(0){
        cout<<"dist: "<<p[0]<<' '<<p[1]<<' '<<p[2]<<' '<<p_pts[3]<<' '<<p_pts[4]<<' '<<p_pts[5]<<' '<<
              Kernal_Function_2p(p,p_pts+3)<<endl;
        for(int i=0;i<npt;++i)cout<<kern(i)<<' ';
        for(int i=0;i<bsize;++i)cout<<kb(i)<<' ';
        cout<<endl;
    }

    double re = loc_part + poly_part;
    return re;

}
static RBF_Core * s_hrbf;
double RBF_Core::Dist_Function(const R3Pt &in_pt){
    return s_hrbf->Dist_Function(&(in_pt[0]));
}

//FT RBF_Core::Dist_Function(const Point_3 in_pt){

//    return s_hrbf->Dist_Function(&(in_pt.x()));
//}

void RBF_Core::SetThis(){

    s_hrbf = this;
}

void RBF_Core::Write_Surface(string fname){

    //writeObjFile(fname,finalMesh_v,finalMesh_fv);

    writePLYFile_VF(fname,finalMesh_v,finalMesh_fv);
}

/**********************************************************/

void RBF_Core::Record(RBF_METHOD method, RBF_Kernal kernal, Solution_Struct &rsol, double time){

    npoints.push_back(npt);

    record_initmethod.push_back(mp_RBF_INITMETHOD[curInitMethod]);
    record_method.push_back(mp_RBF_METHOD[method]);
    record_kernal.push_back(mp_RBF_Kernal[kernal]);
    record_initenergy.push_back(rsol.init_energy);
    record_energy.push_back(rsol.energy);
    record_time.push_back(time);

    setup_timev.push_back(setup_time);
    init_timev.push_back(init_time);
    solve_timev.push_back(solve_time);
    callfunc_timev.push_back(callfunc_time);
    invM_timev.push_back(invM_time);
    setK_timev.push_back(setK_time);

}

void RBF_Core::Record(){

    //cout<<"record"<<endl;
    npoints.push_back(npt);

    record_initmethod.push_back(mp_RBF_INITMETHOD[curInitMethod]);
    record_method.push_back(mp_RBF_METHOD[curMethod]);
    //record_kernal.push_back(mp_RBF_Kernal[kernal]);
    record_initenergy.push_back(sol.init_energy);
    record_energy.push_back(sol.energy);
    //cout<<"record"<<endl;

//    setup_timev.push_back(setup_time);
//    init_timev.push_back(init_time);
//    solve_timev.push_back(solve_time);
//    callfunc_timev.push_back(callfunc_time);
//    invM_timev.push_back(invM_time);
//    setK_timev.push_back(setK_time);
   // cout<<"record end"<<endl;
}

void RBF_Core::AddPartition(string pname){

    record_partition.push_back(record_method.size());
    record_partition_name.push_back(pname);
}

void RBF_Core::Print_Record(){

    cout<<"Method\t\t Kernal\t\t Energy\t\t Time"<<endl;
    cout<<std::setprecision(8)<<endl;
    if(record_partition.size()==0){
        for(int i=0;i<record_method.size();++i){
            cout<<record_method[i]<<"\t\t"<<record_kernal[i]<<"\t\t"<<record_energy[i]<<"\t\t"<<record_time[i]<<endl;
        }
        for(int i=0;i<setup_timev.size();++i){
            cout<<setup_timev[i]<<"\t\t"<<init_timev[i]<<"\t\t"<<solve_timev[i]<<"\t\t"<<callfunc_timev[i]<<"\t\t"<<invM_timev[i]<<"\t\t"<<setK_timev[i]<<endl;
        }
    }else{
        for(int j=0;j<record_partition.size();++j){
            cout<<record_partition_name[j]<<endl;
            for(int i=j==0?0:record_partition[j-1];i<record_partition[j];++i){
                cout<<record_method[i]<<"\t\t"<<record_kernal[i]<<"\t\t"<<record_energy[i]<<"\t\t"<<record_time[i]<<endl;
            }
            for(int i=j==0?0:record_partition[j-1];i<record_partition[j];++i){
                cout<<setup_timev[i]<<"\t\t"<<init_timev[i]<<"\t\t"<<solve_timev[i]<<"\t\t"<<callfunc_timev[i]<<endl;
            }
        }
    }

}

void RBF_Core::Print_TimerRecord(string fname){

    ofstream fout(fname);
    fout<<setprecision(5);
    if(!fout.fail()){
        for(int i=0;i<setup_timev.size();++i){
            fout<<npoints[i]<<'\t'<<setup_timev[i]<<"\t"<<init_timev[i]<<"\t"<<solve_timev[i]<<"\t"<<callfunc_timev[i]<<"\t"<<invM_timev[i]<<"\t"<<setK_timev[i]<<endl;
        }
    }
    fout.close();

}

void RBF_Core::Print_TimerRecord_Single(string fname){

    ofstream fout(fname);
    fout<<setprecision(5);
    if(!fout.fail()){
        fout<<"number of points: "<<npt<<endl
           <<"setup_time (Compute H): "<<setup_time<<" s"<<endl
          <<"init_time (Optimize g/Eigen): "<<init_time<<" s"<<endl
         <<"solve_time (Optimize g/LBFGS): "<<solve_time<<" s"<<endl
        <<"surfacing_time: "<<surf_time<<" s"<<endl;
    }
    fout.close();
}

void RBF_Core::Clear_TimerRecord(){
    npoints.clear();
    setup_timev.clear();
    init_timev.clear();
    solve_timev.clear();
    callfunc_timev.clear();
    invM_timev.clear();
    setK_timev.clear();

}

ext: cpp

max_stars_repo_name: jpanetta/VIPSS

max_issues_repo_name: jpanetta/VIPSS

max_forks_repo_name: jpanetta/VIPSS


text:
#ifndef ELASTY_CLOTH_SIM_OBJECT_HPP
#define ELASTY_CLOTH_SIM_OBJECT_HPP

#include <Eigen/Core>
#include <Eigen/Geometry>
#include <elasty/sim-object.hpp>
#include <string>

namespace elasty
{
    class ClothSimObject : public SimObject
    {
    public:
        enum class InPlaneStrategy
        {
            EdgeDistance,
            ContinuumTriangle,
            Both,
        };

        enum class OutOfPlaneStrategy
        {
            Bending,
            IsometricBending,
            Cross,
        };

        using TriangleList = Eigen::Matrix<std::int32_t, Eigen::Dynamic, 3, Eigen::RowMajor>;
        using UvList       = Eigen::Matrix<float, Eigen::Dynamic, 2 * 3, Eigen::RowMajor>;

        ClothSimObject(const unsigned           resolution,
                       const double             in_plane_stiffness      = 1.000,      ///< PBD
                       const double             in_plane_compliance     = 0.001,      ///< XPBD
                       const double             out_of_plane_stiffness  = 0.100,      ///< PBD
                       const double             out_of_plane_compliance = 0.010,      ///< XPBD
                       const double             dt                      = 1.0 / 60.0, ///< XPBD
                       const Eigen::Affine3d&   transform               = Eigen::Affine3d::Identity(),
                       const InPlaneStrategy    in_plane_strategy       = InPlaneStrategy::Both,
                       const OutOfPlaneStrategy out_of_plane_strategy   = OutOfPlaneStrategy::IsometricBending);

        TriangleList m_triangle_list;
        UvList       m_uv_list;

        bool hasUv() const { return m_uv_list.size() != 0; }

        /// \brief Getter of the areas of the triangles.
        const Eigen::VectorXd& getAreaList() const { return m_area_list; }

        /// \brief Apply aerodynamic forces to the relevant particles.
        ///
        /// \details The aerodynamics model is based on [Wilson+14]. This member function is intended to be called in
        /// the setExternalForces() routine in engines.
        ///
        /// \param drag_coeff The coefficient for drag forces. This value should be larger than lift_coeff.
        ///
        /// \param lift_coeff The coefficient for lift forces. This value should be smaller than drag_coeff.
        void applyAerodynamicForces(const Eigen::Vector3d& global_velocity = Eigen::Vector3d::Zero(),
                                    const double           drag_coeff      = 0.100,
                                    const double           lift_coeff      = 0.060);

    private:
        Eigen::VectorXd m_area_list;

        /// \brief Calculate areas of the triangles.
        ///
        /// \details The result will be stored in m_area_list. This function needs to be called only once.
        void calculateAreas();
    };
} // namespace elasty

#endif // ELASTY_CLOTH_SIM_OBJECT_HPP

ext: hpp

max_stars_repo_name: yuki-koyama/elasty

max_issues_repo_name: yuki-koyama/elasty

max_forks_repo_name: yuki-koyama/elasty


text:
// mge - Modern Game Engine
// Copyright (c) 2021 by Alexander Schroeder
// All rights reserved.
#include "mge/core/dllexport.hpp"
#include "mge/core/trace_sink.hpp"
#include <boost/circular_buffer.hpp>

namespace mge {
    /**
     * @brief Memory trace sink.
     * A memory trace sink stores trace records in a circular buffer. It is used
     * to capture trace records which may get finally published using another
     * sink.
     */
    class MGECORE_EXPORT memory_trace_sink : public trace_sink
    {
    private:
        struct record : trace_record
        {
            record() = default;
            record(const trace_record& r);
            record(const record&) = default;
            record(record&&) = default;

            record&     operator=(record&&) = default;
            record&     operator=(const record&) = default;
            std::string materialized_message;
        };

        using record_buffer = boost::circular_buffer<record>;

    public:
        /**
         * @brief Type of this sink's capacity.
         */
        using capacity_type = record_buffer::capacity_type;
        /**
         * @brief Type of this sink's size.
         */
        using size_type = record_buffer::size_type;

        memory_trace_sink();
        ~memory_trace_sink();

        void publish(const trace_record& r) override;

        /**
         * @brief Capacity of this sink.
         *
         * @return current capacity of this sink, i.e. number of trace records
         * that can be stored
         */
        capacity_type capacity() const;
        /**
         * @brief Set the capacity of this sink.
         *
         * @param c new capacity
         */
        void set_capacity(capacity_type c);
        /**
         * @brief Size of this sink, i.e. number of stored records.
         *
         * @return number of stored records
         */
        size_type size() const;
        /**
         * @brief Clears the sink.
         */
        void clear();

        /**
         * @brief Forwards all entries to another sink.
         *
         * @param sink target sink
         */
        void forward(trace_sink& sink);

    private:
        record_buffer m_records;
    };

} // namespace mge

max_stars_repo_name: mge-engine/mge

max_issues_repo_name: mge-engine/mge

max_forks_repo_name: mge-engine/mge


text:
#include "arc_utilities/first_order_deformation.h"

#include <queue>
#include <Eigen/Core>

using namespace arc_utilities;
using namespace FirstOrderDeformation;

static double ConfigTypeDistance(const ConfigType& c1, const ConfigType& c2)
{
    return Eigen::Vector2d((double)(c1.first - c2.first), (double)(c1.second - c2.second)).norm();
}

static std::vector<ConfigType> GetNeighbours(const ConfigType& config, const ssize_t rows, const ssize_t cols, const ValidityCheckFnType& validity_check_fn)
{
    std::vector<ConfigType> neighbours;
    neighbours.reserve(8);

    const ssize_t row_min = std::max(0L, config.first - 1);
    const ssize_t row_max = std::min(rows - 1, config.first + 1);

    const ssize_t col_min = std::max(0L, config.second - 1);
    const ssize_t col_max = std::min(cols - 1, config.second + 1);

    for (ssize_t col = col_min; col <= col_max; col++)
    {
        for (ssize_t row = row_min; row <= row_max; row++)
        {
            if (!(row == config. first && col == config.second) && validity_check_fn(row, col) == true)
            {
                neighbours.push_back(ConfigType(row, col));
            }
        }
    }

    return neighbours;
}

bool FirstOrderDeformation::CheckFirstOrderDeformation(const ssize_t rows, const ssize_t cols, const ValidityCheckFnType& validity_check_fn)
{
    struct BestFirstSearchComparator
    {
        public:
            // Defines a "less" operation"; by using "greater" the smallest element will appear at the top of the priority queue
            bool operator()(const ConfigAndDistType& c1, const ConfigAndDistType& c2) const
            {
                // We want to explore the one with the smaller expected distance
                return (c1.second > c2.second);
            }
    };

    assert(rows > 0 && cols > 0);
    typedef Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> ArrayXb;

    // Setup the strucutres needed to keep track of the search
    std::priority_queue<ConfigAndDistType, std::vector<ConfigAndDistType>, BestFirstSearchComparator> frontier;
    ArrayXb explored = ArrayXb::Constant(rows, cols, false);

    // Setup the start and goal
    const ConfigType start(0, 0), goal(rows - 1, cols - 1);
    const double start_heuristic_distance = ConfigTypeDistance(start, goal);
    frontier.push(ConfigAndDistType(start, start_heuristic_distance));

    // Perform the best first search
    bool path_found = false;
    while (!path_found && frontier.size() > 0)
    {
        const ConfigAndDistType current = frontier.top();
        frontier.pop();
        const ConfigType& current_config = current.first;

        if (current_config.first == goal.first && current_config.second == goal.second)
        {
            path_found = true;
        }
        // Double check if we've already explored this node:
        //    a single node can be inserted into the frontier multiple times at the same or different priorities
        //    so we want to avoid the expense of re-exploring it, and just discard this one once we pop it
        else if (explored(current_config.first, current_config.second) == false)
        {
            explored(current_config.first, current_config.second) = true;

            // Expand the node to find all neighbours, adding them to the frontier if we have not already explored them
            const auto neighbours = GetNeighbours(current_config, rows, cols, validity_check_fn);
            for (const auto neighbour : neighbours)
            {
                // Check if we've already explored this neighbour to avoid re-adding it to the frontier
                if (explored(neighbour.first, neighbour.second) == false)
                {
                    // We only need the heuristic distance as we are doing a best first search
                    const double neighbour_heuristic_distance = ConfigTypeDistance(neighbour, goal);
                    frontier.push(ConfigAndDistType(neighbour, neighbour_heuristic_distance));
                }
            }
        }
    }

    return path_found;
}