text:
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <vector>
//#include <map>
//#include <set>
#include <unordered_set>
//#include <unordered_map>
#include <cmath>
#include <algorithm>

// #include <gnuplot-iostream.h>
#include <assert.h>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

#include "vector3d.hpp"
#include "swiss_to_lat_lon.hpp"
#include "height_map.hpp"

const int horizon_angles = 360;
const int tile_size = 40;

namespace po = boost::program_options;

struct pos_hoz {
    vector3d pos;
    vector3d norm;
    short elevation_angles[horizon_angles];
    pos_hoz() : pos(0,0,0), norm(0,0,0) {
        memset(elevation_angles, 0, sizeof(short) * horizon_angles);
    }
};

bool EQ_DBL(double a, double b){
    return std::abs(a-b)<EPS_DBL;
}

int main(int ac, char** av) {

    bool test = true;
    //Variables to be assigned by program options
    double height_map_resolution = 25.0;;
    double north_bound = 1e100;
    double south_bound = -1e100;
    double east_bound = 1e100;
    double west_bound = -1e100;

    std::string input_file;
    std::string output_file;
    bool verbose = false;

    /*
    // Declare the supported options.
    po::options_description op_desc("Allowed options");

    op_desc.add_options()
    ("help", "print options table")
    ("input-file,i", po::value<std::string>(&input_file), "File containing height map data in x<space>y<space>z<newline> swiss coordinates format")
    ("output-dir,o", po::value<std::string>(&output_file), "File for output data (default data_out.hoz)")
    ("resolution,R", po::value<double>(&height_map_resolution)->default_value(25.0), "resolution of data (default: 25.0)")
    ("nmax",po::value<double>(&north_bound)->default_value(1e100), "maximum north coordinate to be treated (default 1e100)")
    ("nmin",po::value<double>(&south_bound)->default_value(-1e100), "minimum north coordinate to be treated (default -1e100)")
    ("emax",po::value<double>(&east_bound)->default_value(1e100), "maximum east coordinate to be treated (default 1e100)")
    ("emin",po::value<double>(&west_bound)->default_value(-1e100), "minimum east coordinate to be treated (default -1e100)")
    ("verbose, v", "Verbose: output lots of text")
    ;

    po::positional_options_description pd;
    pd.add("input-file", 1).add("output-file", 1);

    po::variables_map vm;
    po::store(po::parse_command_line(ac, av, op_desc), vm);
    po::notify(vm);

    if (vm.count("help")) {
        std::cout <<"MountainOutline [options] [input file] [output base]"<<std::endl<< op_desc << std::endl;
        return 1;
    }

    if (vm.count("verbose")){
        verbose = true;
    }
    if(!vm.count("input-file")){
        std::cout << "Input file must be specified" << std::endl;
        exit(255);
    }
    if(!vm.count("output-dir")){
        output_file = std::string("data_out.hoz");
        std::cout << "Output directory will be: " << std::endl;
    }
    */
    input_file = std::string("/Users/alexxx/HeightMaps/precieous/DHM25.xyz");
    std::ifstream ifs(input_file);
    if (!ifs.is_open())
        throw std::runtime_error("could not open file : " + std::string(input_file));

    height_map grid_points(ifs, south_bound, north_bound, east_bound, west_bound);

    //grid_points is a height_map, an unordered_set of all points in bounding box with
    //the maximum and minimum x,y,h of all values stored.

    std::pair<double,double> NE = swiss_to_lat_lon(grid_points.xmax()+height_map_resolution/2.0, grid_points.ymax()+height_map_resolution/2.0);
    std::pair<double,double> SW = swiss_to_lat_lon(grid_points.xmin()-height_map_resolution/2.0, grid_points.ymin()-height_map_resolution/2.0);

    std::cout << "NE: " << grid_points.xmax() <<", " << grid_points.ymax() << " SW: "<< grid_points.xmin() << " , " << grid_points.ymin() <<  std::endl;
    std::cout  << "NE: " << NE.first <<", " << NE.second << " SW: "<< SW.first << ", " << SW.second <<  std::endl;
    std::cout << "Maximum height: " << grid_points.hmax() << std::endl;
    std::cout << "Number of points in dataset: " << grid_points.size() << std::endl;

    if(test){
        double y_test = height_map_resolution*floor(601430.0/height_map_resolution);
        double x_test = height_map_resolution*floor(126243.0/height_map_resolution);
        auto it_v = grid_points.find_point(vector3d(x_test,y_test,0));      //get the gridpoint from the set
        std::cout << "Test point: " << x_test <<" "<< y_test << std::endl;
        std::cout << "Resolution: " << height_map_resolution << ", tile size: "<< tile_size << std::endl;
        vector3d v = *it_v;
        double elevation_angles[360];
        int theta_start = 0;
        int theta_end = 360;

        //        time_t start_time  = time(NULL);
        clock_t t = clock();
        for(int theta = theta_start;theta<theta_end;theta++){
            double phi = atan(grid_points.compute_elevation_angle(v,theta, height_map_resolution, 360.0/horizon_angles));
            short phi_short = (short)((phi / M_PI_2) * std::numeric_limits<short>::max());
            elevation_angles[theta] = phi_short;

        }
        double run_time = ((double)(clock()-t))/CLOCKS_PER_SEC;
        //        double run_time = difftime(time(NULL), start_time);
        std::cout << "phi = [";
        for(int theta = theta_start;theta<theta_end;theta++){
            std::cout << elevation_angles[theta] << ";";
        }
        std::cout << "];" << std::endl;
        std::cout << "runtime test point: " << run_time << std::endl;

        return 0;
    }

    return 0;
}

max_stars_repo_name: alexxxzzz/ValaisSun

max_issues_repo_name: alexxxzzz/ValaisSun

max_forks_repo_name: alexxxzzz/ValaisSun


text:
// Copyright (c) 2012-2018 The Elastos Open Source Project
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#define CATCH_CONFIG_MAIN

#include <catch.hpp>
#include <SDK/SpvService/Config.h>
#include <SDK/Common/Log.h>
#include <SDK/P2P/ChainParams.h>

#include <fstream>
#include <boost/filesystem.hpp>

using namespace Elastos::ElaWallet;

TEST_CASE("Config test", "[Config]") {
	Log::registerMultiLogger();

	SECTION("ELA") {
		const std::string chainID = "ELA";
		const std::string genesisAddress = "";
		const std::string pluginType = "ELA";
		uint32_t index = 0;

		SECTION("MainNet") {
			const std::string netType = "MainNet";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 20338);
			REQUIRE(chainParams->MagicNumber() == 2017001);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-mainnet-002.elastos.org");
			REQUIRE(dnsSeed[1] == "node-mainnet-006.elastos.org");
			REQUIRE(dnsSeed[2] == "node-mainnet-014.elastos.org");
			REQUIRE(dnsSeed[3] == "node-mainnet-016.elastos.org");
			REQUIRE(dnsSeed[4] == "node-mainnet-021.elastos.org");
			REQUIRE(dnsSeed[5] == "node-mainnet-003.elastos.org");
			REQUIRE(dnsSeed[6] == "node-mainnet-007.elastos.org");
			REQUIRE(dnsSeed[7] == "node-mainnet-017.elastos.org");
			REQUIRE(dnsSeed[8] == "node-mainnet-022.elastos.org");
			REQUIRE(dnsSeed[9] == "node-mainnet-004.elastos.org");
			REQUIRE(dnsSeed[10] == "node-mainnet-023.elastos.org");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("05f458a5522851622cae2bb138498dec60a8f0b233802c97a1ca41f9f214708d"));
			REQUIRE(checkPoints[0].Height() == 0);
		}

		SECTION("TestNet") {
			const std::string netType = "TestNet";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 21338);
			REQUIRE(chainParams->MagicNumber() == 2018101);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-testnet-005.elastos.org");
			REQUIRE(dnsSeed[1] == "node-testnet-006.elastos.org");
			REQUIRE(dnsSeed[2] == "node-testnet-007.elastos.org");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("6418be20291bc857c9a01e5ba205445b85a0593d47cc0b576d55a55e464f31b3"));
			REQUIRE(checkPoints[0].Height() == 0);
		}

		SECTION("RegTest") {
			const std::string netType = "RegTest";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 22338);
			REQUIRE(chainParams->MagicNumber() == 2018211);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-regtest-105.eadd.co");
			REQUIRE(dnsSeed[1] == "node-regtest-106.eadd.co");
			REQUIRE(dnsSeed[2] == "node-regtest-107.eadd.co");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("6418be20291bc857c9a01e5ba205445b85a0593d47cc0b576d55a55e464f31b3"));
			REQUIRE(checkPoints[0].Height() == 0);
		}

	}

	SECTION("IDChain") {
		const std::string chainID = "IDChain";
		const std::string genesisAddress = "XKUh4GLhFJiqAMTF6HyWQrV9pK9HcGUdfJ";
		const std::string pluginType = "SideStandard";
		uint32_t index = 1;

		SECTION("MainNet") {
			const std::string netType = "MainNet";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index()== index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 20608);
			REQUIRE(chainParams->MagicNumber() == 2017002);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-mainnet-026.elastos.org");
			REQUIRE(dnsSeed[1] == "node-mainnet-027.elastos.org");
			REQUIRE(dnsSeed[2] == "node-mainnet-028.elastos.org");
			REQUIRE(dnsSeed[3] == "node-mainnet-029.elastos.org");
			REQUIRE(dnsSeed[4] == "node-mainnet-030.elastos.org");
			REQUIRE(dnsSeed[5] == "node-mainnet-031.elastos.org");
			REQUIRE(dnsSeed[6] == "node-mainnet-032.elastos.org");
			REQUIRE(dnsSeed[7] == "node-mainnet-033.elastos.org");
			REQUIRE(dnsSeed[8] == "node-mainnet-034.elastos.org");
			REQUIRE(dnsSeed[9] == "node-mainnet-035.elastos.org");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("56be936978c261b2e649d58dbfaf3f23d4a868274f5522cd2adb4308a955c4a3"));
			REQUIRE(checkPoints[0].Height() == 0);
		}

		SECTION("TestNet") {
			const std::string netType = "TestNet";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 21608);
			REQUIRE(chainParams->MagicNumber() == 2018102);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-testnet-011.elastos.org");
			REQUIRE(dnsSeed[1] == "node-testnet-012.elastos.org");
			REQUIRE(dnsSeed[2] == "node-testnet-013.elastos.org");
			REQUIRE(dnsSeed[3] == "node-testnet-014.elastos.org");
			REQUIRE(dnsSeed[4] == "node-testnet-015.elastos.org");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("56be936978c261b2e649d58dbfaf3f23d4a868274f5522cd2adb4308a955c4a3"));
			REQUIRE(checkPoints[0].Height() == 0);
		}

		SECTION("RegTest") {
			const std::string netType = "RegTest";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 22608);
			REQUIRE(chainParams->MagicNumber() == 2018202);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-regtest-116.eadd.co");
			REQUIRE(dnsSeed[1] == "node-regtest-117.eadd.co");
			REQUIRE(dnsSeed[2] == "node-regtest-118.eadd.co");
			REQUIRE(dnsSeed[3] == "node-regtest-119.eadd.co");
			REQUIRE(dnsSeed[4] == "node-regtest-120.eadd.co");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("56be936978c261b2e649d58dbfaf3f23d4a868274f5522cd2adb4308a955c4a3"));
			REQUIRE(checkPoints[0].Height() == 0);
		}
	}

#if 0
	SECTION("TokenChain") {
		const std::string chainID = "TokenChain";
		const std::string genesisAddress = "XVfmhjxGxBKgzYxyXCJTb6YmaRfWPVunj4";
		const std::string pluginType = "SideStandard";
		uint32_t index = 2;

		SECTION("MainNet") {
			const std::string netType = "MainNet";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index()== index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 20618);
			REQUIRE(chainParams->MagicNumber() == 2019004);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-mainnet-002.elastos.org");
			REQUIRE(dnsSeed[1] == "node-mainnet-003.elastos.org");
			REQUIRE(dnsSeed[2] == "node-mainnet-004.elastos.org");
			REQUIRE(dnsSeed[3] == "node-mainnet-005.elastos.org");
			REQUIRE(dnsSeed[4] == "node-mainnet-006.elastos.org");
			REQUIRE(dnsSeed[5] == "node-mainnet-007.elastos.org");
			REQUIRE(dnsSeed[6] == "node-mainnet-008.elastos.org");
			REQUIRE(dnsSeed[7] == "node-mainnet-009.elastos.org");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[4].Hash() == uint256("ca8df7f2004dc5ff3b500967a24fc1f1d709ff804119ea86f9fc05d85de9dec6"));
			REQUIRE(checkPoints[4].Height() == 8064);
			REQUIRE(checkPoints[5].Hash() == uint256("58b25e8f4aed9346b8e23b224242ddb2f42d8d6c7d00077beaf97684ca02474e"));
			REQUIRE(checkPoints[5].Height() == 10080);
		}

		SECTION("TestNet") {
			const std::string netType = "TestNet";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 21618);
			REQUIRE(chainParams->MagicNumber() == 2019104);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-testnet-002.elastos.org");
			REQUIRE(dnsSeed[1] == "node-testnet-003.elastos.org");
			REQUIRE(dnsSeed[2] == "node-testnet-004.elastos.org");
			REQUIRE(dnsSeed[3] == "node-testnet-005.elastos.org");
			REQUIRE(dnsSeed[4] == "node-testnet-006.elastos.org");
			REQUIRE(dnsSeed[5] == "node-testnet-007.elastos.org");
			REQUIRE(dnsSeed[6] == "node-testnet-011.elastos.org");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("b569111dfb5e12d40be5cf09e42f7301128e9ac7ab3c6a26f24e77872b9a730e"));
			REQUIRE(checkPoints[0].Height() == 0);
		}

		SECTION("RegTest") {
			const std::string netType = "RegTest";
			Config config("Data", netType);

			ChainConfigPtr chainConfig = config.GetChainConfig(chainID);
			REQUIRE(chainConfig->ID() == chainID);
			REQUIRE(chainConfig->Index() == index);
			REQUIRE(chainConfig->NetType() == "MainNet");
			REQUIRE(chainConfig->MinFee() == 10000);
			REQUIRE(chainConfig->FeePerKB() == 10000);
			REQUIRE(chainConfig->DisconnectionTime() == 300);
			REQUIRE(chainConfig->PluginType() == pluginType);
			REQUIRE(chainConfig->GenesisAddress() == genesisAddress);

			const ChainParamsPtr &chainParams = chainConfig->ChainParameters();
			REQUIRE(chainParams->StandardPort() == 22618);
			REQUIRE(chainParams->MagicNumber() == 2019204);
			REQUIRE(chainParams->Services() == 0);
			REQUIRE(chainParams->TargetTimeSpan() == 86400);
			REQUIRE(chainParams->TargetTimePerBlock() == 120);

			const std::vector<std::string> &dnsSeed = chainParams->DNSSeeds();
			REQUIRE(dnsSeed[0] == "node-regtest-102.eadd.co");
			REQUIRE(dnsSeed[1] == "node-regtest-103.eadd.co");
			REQUIRE(dnsSeed[2] == "node-regtest-104.eadd.co");
			REQUIRE(dnsSeed[3] == "node-regtest-105.eadd.co");
			REQUIRE(dnsSeed[4] == "node-regtest-106.eadd.co");
			REQUIRE(dnsSeed[5] == "node-regtest-107.eadd.co");

			const std::vector<CheckPoint> &checkPoints = chainParams->Checkpoints();
			REQUIRE(checkPoints[0].Hash() == uint256("b569111dfb5e12d40be5cf09e42f7301128e9ac7ab3c6a26f24e77872b9a730e"));
			REQUIRE(checkPoints[0].Height() == 0);
		}
	}
#endif

}

ext: cpp


text:
//==============================================================================
//         Copyright 2003 - 2012   LASMEA UMR 6602 CNRS/Univ. Clermont II
//         Copyright 2009 - 2012   LRI    UMR 8623 CNRS/Univ Paris Sud XI
//
//          Distributed under the Boost Software License, Version 1.0.
//                 See accompanying file LICENSE.txt or copy at
//                     http://www.boost.org/LICENSE_1_0.txt
//==============================================================================
#include <boost/simd/operator/include/functions/is_equal.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <boost/simd/sdk/simd/logical.hpp>

#include <boost/dispatch/functor/meta/call.hpp>
#include <boost/simd/sdk/simd/native.hpp>
#include <nt2/sdk/unit/tests/relation.hpp>
#include <nt2/sdk/unit/tests/type_expr.hpp>
#include <nt2/sdk/unit/module.hpp>
#include <boost/simd/sdk/config.hpp>
#include <boost/simd/sdk/simd/io.hpp>

#include <boost/simd/include/constants/one.hpp>
#include <boost/simd/include/constants/mone.hpp>
#include <boost/simd/include/constants/zero.hpp>
#include <boost/simd/include/constants/inf.hpp>
#include <boost/simd/include/constants/minf.hpp>
#include <boost/simd/include/constants/nan.hpp>
#include <boost/simd/include/constants/false.hpp>
#include <boost/simd/include/constants/true.hpp>
#include <boost/simd/include/constants/valmax.hpp>
#include <boost/simd/include/constants/valmin.hpp>

NT2_TEST_CASE_TPL ( is_equal_integer,  BOOST_SIMD_SIMD_TYPES)
{
  using boost::simd::is_equal;
  using boost::simd::tag::is_equal_;
  using boost::simd::native;
  using boost::simd::True;
  using boost::simd::False;
  typedef BOOST_SIMD_DEFAULT_EXTENSION  ext_t;
  typedef native<T,ext_t>                  vT;
  typedef typename boost::dispatch::meta::call<is_equal_(vT,vT)>::type r_t;

  NT2_TEST_EQUAL(is_equal(boost::simd::Valmax<vT>(), boost::simd::Valmin<vT>()), False<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Valmax<vT>(), boost::simd::Valmax<vT>()), True<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Valmin<vT>(), boost::simd::Valmax<vT>()), False<r_t>());
}

NT2_TEST_CASE_TPL ( is_equal_signed_integer,  BOOST_SIMD_SIMD_INTEGRAL_SIGNED_TYPES)
{
  using boost::simd::is_equal;
  using boost::simd::tag::is_equal_;
  using boost::simd::native;
  using boost::simd::True;
  using boost::simd::False;
  typedef BOOST_SIMD_DEFAULT_EXTENSION  ext_t;
  typedef native<T,ext_t>                  vT;
  typedef typename boost::dispatch::meta::call<is_equal_(vT,vT)>::type r_t;

  NT2_TEST_EQUAL(is_equal(boost::simd::Zero<vT>(), boost::simd::Mone<vT>()), False<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Zero<vT>(), boost::simd::One<vT>()) , False<r_t>());
}

NT2_TEST_CASE_TPL ( is_equal_real,  BOOST_SIMD_SIMD_REAL_TYPES)
{
  using boost::simd::is_equal;
  using boost::simd::tag::is_equal_;
  using boost::simd::native;
  using boost::simd::True;
  using boost::simd::False;
  typedef BOOST_SIMD_DEFAULT_EXTENSION  ext_t;
  typedef native<T,ext_t>                  vT;
  typedef typename boost::dispatch::meta::call<is_equal_(vT,vT)>::type r_t;

  NT2_TEST_EQUAL(is_equal(boost::simd::Inf<vT>() , boost::simd::Inf<vT>()) , True<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Minf<vT>(), boost::simd::Minf<vT>()), True<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Inf<vT>() , boost::simd::Minf<vT>()), False<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Nan<vT>() , boost::simd::Nan<vT>()) , False<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Zero<vT>(), boost::simd::Mone<vT>()), False<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::Zero<vT>(), boost::simd::One<vT>()) , False<r_t>());
}

NT2_TEST_CASE_TPL ( is_equall,  BOOST_SIMD_SIMD_TYPES)
{
  using boost::simd::is_equal;
  using boost::simd::tag::is_equal_;
  using boost::simd::native;
  using boost::simd::True;
  using boost::simd::False;
  typedef BOOST_SIMD_DEFAULT_EXTENSION  ext_t;
  typedef native<T,ext_t>                  vT;
  typedef native< boost::simd::logical<T>, ext_t> vlT;
  typedef typename boost::dispatch::meta::call<is_equal_(vT,vT)>::type r_t;

  // specific values tests
  NT2_TEST_EQUAL(is_equal(boost::simd::True<vlT>(),boost::simd::False<vlT>()), False<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::True<vlT>(), boost::simd::True<vlT>()), True<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::False<vlT>(),boost::simd::False<vlT>()), True<r_t>());
  NT2_TEST_EQUAL(is_equal(boost::simd::False<vlT>(), boost::simd::True<vlT>()), False<r_t>());
} // end of test for floating_


text:
#include "visual_utility/VisualUtilityEstimator.h"

#include <ros/ros.h>
#include <rosbag/view.h>
#include <limits>
#include <math.h>
#include <boost/scoped_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/functional/hash.hpp>
#include <boost/unordered_map.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <algorithm>
#include "visual_utility/cvutils-inl.h"
#include "cv_utils/DisplayImages.h"
#include "cv_utils/IntegralHistogram-Inl.h"
#include "visual_utility/Parameter.h"
#include "visual_utility/VisualUtilityEstimation.h"
#include "base/StringHash.h"
#include "visual_utility/VisualUtilityROSParams.h"
#include "hog_detector/integral_hog_detector_inl.h"

using namespace cv;
using namespace boost;
using namespace std;

namespace cv {
inline std::size_t hash_value(const cv::Rect& key) {
  size_t seed = 7823;
  hash_combine(seed, key.x);
  hash_combine(seed, key.y);
  hash_combine(seed, key.height);
  hash_combine(seed, key.width);
  return seed;
}

inline std::size_t hash_value(const cv::Size& key) {
  size_t seed = 54326;
  hash_combine(seed, key.height);
  hash_combine(seed, key.width);
  return seed;
}
} // end namespace

namespace visual_utility {

// ---------- Start VisualUtilityEstimator -----------

VisualUtilityEstimator::~VisualUtilityEstimator() {}

const Mat* VisualUtilityEstimator::GetLastTransform() const {
  return NULL;
}

void VisualUtilityEstimator::CalculateVisualUtility(
  const string& filename,
  const vector<Rect>& rois,
  double time,
  std::vector<ROIScore>* vuOut) {
  // Open up the file
  Mat cvImage = imread(filename);

  // Calculate the visual utility
  CalculateVisualUtility(cvImage, rois, time, vuOut);
}

void VisualUtilityEstimator::CalculateVisualUtility(
  const cv::Mat& image,
  const vector<Rect>& rois,
  double time,
  std::vector<ROIScore>* vuOut) {

  ROS_ASSERT(vuOut);
  lastRuntime_.reset(NULL);

  // Start by initializing anything that's needed with the image
  ros::WallTime startTime = ros::WallTime::now();
  InitBoxCalculator(image, time);
  ros::WallDuration initTime = ros::WallTime::now() - startTime;

  ROS_INFO_STREAM("Processing time for initialization: " << initTime.toSec());

  // Now collect all the rois of interest for each box size
  unordered_map<Size, shared_ptr<PointScores> > pointLists;
  vuOut->resize(rois.size());
  int i = 0;
  for(vector<Rect>::const_iterator regionI = rois.begin();
      regionI != rois.end(); ++regionI, ++i) {
    Size winSize(regionI->width, regionI->height);
    unordered_map<Size, shared_ptr<PointScores> >::iterator pointsPtr =
      pointLists.find(winSize);
    if (pointsPtr == pointLists.end()) {
      pointsPtr = pointLists.insert(pair<Size, shared_ptr<PointScores> >(
        winSize,
        shared_ptr<PointScores>(new PointScores()))).first;
    }
    (*vuOut)[i].second = *regionI;
    pointsPtr->second->push_back(pair<double*, Point>(&((*vuOut)[i].first),
                                                      Point(regionI->x,
                                                            regionI->y)));
  }

  // Now for each box size, calculate the visual utility scores across
  // the image.
  startTime = ros::WallTime::now();
  for(unordered_map<Size, shared_ptr<PointScores> >::const_iterator
        pointsI = pointLists.begin();
      pointsI != pointLists.end(); ++pointsI) {
    CalculateVisualUtilityBoxAcrossImage(pointsI->first.width,
                                         pointsI->first.height,
                                         *pointsI->second);
  }

  ros::WallDuration calculationTime = ros::WallTime::now() - startTime;
  ROS_INFO_STREAM("Processing time for calculation: " << calculationTime);
  if (lastRuntime_.get() == NULL) {
    lastRuntime_.reset(new double((initTime + calculationTime).toSec()));
  }
}

// Helper function for the following CalculateVisualUtility that
// creates a list of points to evaluate at based on a grid and a mask.
void VisualUtilityEstimator::GetLocationsForEvaluation(
  const Mat& image,
  int minX, int minY,
  int strideX, int strideY,
  double width, double height,
  const Mat& mask,
  Mat& scores,
  PointScores* locations) {
  ROS_ASSERT(mask.empty() || mask.type() == CV_8U);
  ROS_ASSERT(scores.type() == CV_64F);
  ROS_ASSERT(locations);
  locations->clear();

  for (int i = 0, curX = minX; curX < image.cols-width; ++i) {
    for (int j = 0, curY = minY; curY < image.rows-height; ++j) {
      if (mask.empty() || mask.at<uint8_t>(i,j)) {
        locations->push_back(pair<double*, Point>(scores.ptr<double>(i,j),
                                                  Point(curX,curY)));
      }
      curY += strideY;
    }
    curX += strideX;
  }
}

void VisualUtilityEstimator::GetGridHeightsAndWidths(const Mat& image,
                                                     int minX, int minY,
                                                     int minW, int minH,
                                                     double strideW,
                                                     double strideH,
                                                     bool fixAspect,
                                                     vector<double>* widths,
                                                     vector<double>* heights){
  ROS_ASSERT(widths);
  ROS_ASSERT(heights);

  if (fixAspect) {
    strideH = strideW;
  }

  for (double curW = minW; curW < image.cols-minX; curW *= strideW) {
    widths->push_back(cvRound(curW));
  }

  for (double curH = minH; curH < image.rows-minY; curH *= strideH) {
    heights->push_back(cvRound(curH));
  }

  // If the aspect ratio is fixed, truncate the list of sizes to the
  // smaller one.
  if (fixAspect) {
    if (heights->size() > widths->size()) {
      heights->resize(widths->size());
    } else {
      widths->resize(heights->size());
    }
  }

}

void VisualUtilityEstimator::InitializeScoreGrid(
  const Mat& image,
  int minX, int minY,
  int strideX, int strideY,
  bool fixAspect,
  const vector<double>& widths,
  const vector<double>& heights,
  Mat* scoreGrid) {
  ROS_ASSERT(scoreGrid);

  vector<int> scoreSize;
  scoreSize.push_back(widths.size());
  if (!fixAspect) scoreSize.push_back(heights.size());
  scoreSize.push_back(
    std::max<int>(1, (image.cols - minX - widths[0]) / strideX));
  scoreSize.push_back(
    std::max<int>(1, (image.rows - minY - heights[0]) / strideY));
  *scoreGrid = cv::Mat(scoreSize.size(), &scoreSize[0], CV_64F,
                   -numeric_limits<double>::infinity());
}

cv::Mat VisualUtilityEstimator::CalculateVisualUtility(
  const cv::Mat& image,
  int minX, int minY,
  int minW, int minH,
  int strideX, int strideY,
  double strideW, double strideH,
  bool fixAspect,
  double time,
  const cv::Mat& mask) {
  Mat scores;

  lastRuntime_.reset(NULL);

  // Start by initializing anything that's needed with the image
  ros::WallTime startTime = ros::WallTime::now();
  InitBoxCalculator(image, time);
  ros::WallDuration initTime = ros::WallTime::now() - startTime;

  vector<double> widths;
  vector<double> heights;
  GetGridHeightsAndWidths(image, minX, minY, minW, minH, strideW, strideH,
                          fixAspect, &widths, &heights);

  // Build the output score matrix
  InitializeScoreGrid(image, minX, minY, strideX, strideY, fixAspect,
                      widths, heights,
                      &scores);
  ROS_ASSERT(mask.empty() ||
             (mask.dims == scores.dims &&
              mask.size == scores.size));

  // Now walk through the different size of boxes
  PointScores locations;
  ros::WallDuration calculationTime(0);
  for (unsigned int widthI = 0u; widthI < widths.size(); ++widthI) {
    if (fixAspect) {
      Mat scorePlane(2, &scores.size[1], CV_64F,
                     scores.ptr(widthI), &scores.step[1]);
      GetLocationsForEvaluation(image,
                                minX, minY, strideX, strideY,
                                widths[widthI],
                                heights[widthI],
                                (mask.empty() ? mask :
                                 Mat(2, &mask.size[1], mask.type(),
                                     const_cast<uchar*>(mask.ptr(widthI)),
                                     &mask.step[1])),
                                scorePlane,
                                &locations);

      startTime = ros::WallTime::now();
      CalculateVisualUtilityBoxAcrossImage(widths[widthI],
                                           heights[widthI],
                                           locations);
      calculationTime += ros::WallTime::now() - startTime;

    } else {
      for (unsigned int heightI = 0u; heightI < heights.size(); ++heightI) {
        Mat scorePlane(2, &scores.size[2], CV_64F,
                       scores.ptr(widthI, heightI),
                       &scores.step[2]);
        GetLocationsForEvaluation(image,
                                  minX, minY, strideX, strideY,
                                  widths[widthI],
                                  heights[heightI],
                                  (mask.empty() ? mask :
                                   Mat(2, &mask.size[2], mask.type(),
                                       const_cast<uchar*>(mask.ptr(widthI,
                                                                  heightI)),
                                       &mask.step[2])),
                                  scorePlane,
                                  &locations);

        startTime = ros::WallTime::now();
        CalculateVisualUtilityBoxAcrossImage(widths[widthI],
                                             heights[heightI],
                                             locations);
        calculationTime += ros::WallTime::now() - startTime;
      }
    }
  }

  if (lastRuntime_.get() == NULL) {
    lastRuntime_.reset(new double((initTime + calculationTime).toSec()));
  }

  return scores;
}

bool VisualUtilityEstimator::InitBoxCalculator(const cv::Mat& image,
                                               double time) {
  ROS_FATAL("InitBoxCalculator is not implemented");
  ROS_ASSERT(false);
  return false;
}

void VisualUtilityEstimator::CalculateVisualUtilityBoxAcrossImage(
    double width, double height,
    const PointScores& locations) {

  for (PointScores::const_iterator pointI = locations.begin();
       pointI != locations.end();
       ++pointI) {
    *pointI->first = CalculateVisualUtilityOfBox(pointI->second.x,
                                                 pointI->second.y,
                                                 cvRound(height),
                                                 cvRound(width));
  }

}

double VisualUtilityEstimator::CalculateVisualUtilityOfBox(int x, int y,
                                                           int h, int w) {
  ROS_FATAL("Calculating the visual utility of a box is not implemented. "
            "Try wrapping it in one of the wrapper visual "
            "utility estimators like RelativeEntropyVUWrapper");
  ROS_ASSERT(false);
  return 0; // To make compiler happy
}

//-------- Start LABMotionVUEstimator --------------

LABMotionVUEstimator::~LABMotionVUEstimator() {}

const Mat* LABMotionVUEstimator::GetLastTransform() const {
  if (lastTransform_.empty()) {
    return NULL;
  }
  return &lastTransform_;
}

//#define GREY_OVERRIDE 0

cv::Mat_<double> LABMotionVUEstimator::CalculateVisualUtility(
  const Mat& image, double time) {

  if (image.channels() != 3) {
    ROS_ERROR("Image is not in color. We need a BGR image");
    return cv::Mat_<double>();
  }

  if (image.depth() != CV_8U) {
    ROS_FATAL("For speed reasons, the image must be still in its natural "
              "8-bit format");
    return cv::Mat_<double>();
  }

  // Get the LAB and greyscale images
  Mat_<uchar> tmpGreyImage;
  Mat_<double> curGreyImage;
  cvtColor(image, tmpGreyImage, CV_BGR2GRAY);
  tmpGreyImage.convertTo(curGreyImage, CV_64FC1, 1.0/255);

  // The L value in the image is scaled to be 0-255 instead of 0-100,
  // so we need to rescale it
  Mat_<Vec3b> tmpLabImage;
  Mat_<Vec3d> curLabImage;
  cvtColor(image, tmpLabImage, CV_BGR2Lab);
  tmpLabImage.assignTo(curLabImage, CV_64FC3);
  vector<Mat> channels;
  split(curLabImage, channels);
  channels[0] *= 100./255.;
  merge(channels, curLabImage);

  if (lastLabImage_.empty()) {
    // This is the first image added
    lastLabImage_ = curLabImage;
    lastGreyImage_ = curGreyImage;
    return cv::Mat_<double>();
  }

  // Calculate the affine transform to convert the last image to the
  // current one
  Mat lastTransform_ = transformEstimator_.EstimateTransform(lastGreyImage_,
                                                             curGreyImage);

  // Now warp the old image to the current one
#ifdef GREY_OVERRIDE
  Mat_<double> warpedImage;
  if (!lastTransform_.empty()) {
    warpedImage =  transformEstimator_.ApplyTransform(
      lastGreyImage_,
      lastTransform_,
      geo::BORDER_TRANSPARENT,
      0.0,
      curGreyImage);
  } else {
    warpedImage = lastGreyImage_;
  }
#else
  Mat_<Vec3d> warpedImage ;
  if (!lastTransform_.empty()) {
    warpedImage = transformEstimator_.ApplyTransform(
      lastLabImage_,
      lastTransform_,
      geo::BORDER_TRANSPARENT,
      Vec3d(0,0,0),
      curLabImage);
  } else {
    warpedImage = lastLabImage_;
  }
#endif

  // Next calculate the distance between the two images
  Mat_<float> dist(image.rows, image.cols, 0.0);

#ifdef GREY_OVERRIDE
  dist = abs(curGreyImage - warpedImage);
#else
  Mat_<Vec3d> diff = curLabImage - warpedImage;
  diff = diff.mul(diff);

  vector<Mat> diffChannels;
  split(diff, diffChannels);
  for (unsigned int i = 0u; i < diffChannels.size(); i++) {
    add(dist, diffChannels[i], dist, noArray(), CV_32F);
    //dist += diffChannels[i];
  }
  sqrt(dist, dist);
#endif

  lastLabImage_ = curLabImage;
  lastGreyImage_ = curGreyImage;

  // Do erode and dilate (aka openeing)
  morphologyEx(dist, dist, MORPH_OPEN,
               Mat_<int>::ones(openingSize_, openingSize_));

  return dist;
}

// Functor for calculating the sums needed for the alpha calculation
struct SumForAlphaFunctor {
  SumForAlphaFunctor(int& _nValidPixels,
                     double& _paretoSum,
                     double _logMode)
    : nValidPixels(_nValidPixels), paretoSum(_paretoSum), logMode(_logMode){}

  inline void operator()(const double val) {
    const double lVal = log(val);
    if (lVal >= logMode) {
      nValidPixels++;
      paretoSum += lVal - logMode;
    }
  }

  int& nValidPixels;
  double& paretoSum;
  const double logMode;

};

// Functor for building up the histogram
struct FillHistogramFunctor {
  FillHistogramFunctor(vector<double>& hist, double minVal, double maxVal)
    : hist_(hist), minVal_(minVal), maxVal_(maxVal),
      histFactor((hist.size()-1)/(maxVal-minVal)) {}

  inline void operator()(double val) {
    if (val >= minVal_ && val <= maxVal_) {
      hist_[static_cast<int>(histFactor*(val-minVal_))] += val;
    }
  }

  vector<double>& hist_;
  const double minVal_;
  const double maxVal_;
  const double histFactor;
};

double LABMotionVUEstimator::CalculateParetoThreshold(
  const Mat_<double>& dist) {
  // Fist find the range of distance values
  double maxVal;
  double minVal;
  minMaxLoc(dist, &minVal, &maxVal);

  if (minVal == maxVal) {
    return std::numeric_limits<double>::infinity();
  }

  // Calculate the histogram
  const int HIST_SIZE = 256;
  vector<double> hist(HIST_SIZE+1, 0.0);
  double histFactor = ((double)HIST_SIZE)/(maxVal - minVal);
  double bucketSize = 1./histFactor;
  cvutils::ApplyToEachElement<FillHistogramFunctor, double>(dist,
    FillHistogramFunctor(hist, minVal, maxVal));

  // Calculate the mode since we'll ignore points below that
  int modeBucket=0;
  double modeVal = 0;
  for (unsigned int i = 0u; i < hist.size(); ++i) {
    if (hist[i] > modeVal) {
      modeVal = hist[i];
      modeBucket = i;
    }
  }
  double mode = ((double)modeBucket)/histFactor + minVal + bucketSize/2;
  double logMode = log(mode);

  // Now calculate the alpha parameter
  int nValidPixels = 0;
  double paretoSum = 0;
  cvutils::ApplyToEachElement<SumForAlphaFunctor, double>(dist,
    SumForAlphaFunctor(nValidPixels, paretoSum, logMode));
  double alpha = nValidPixels / paretoSum;

  // Alternate way to calcuate alpha using the buckets
  /*int nValidPixels2 = 0;
  double paretoSum2 = 0;
  for (int i = 0; i < HIST_SIZE; ++i) {
    const double bucketCenter = ((double)i)/histFactor + minVal +
      bucketSize/2;
    if (bucketCenter >= mode) {
      nValidPixels2 += hist[i];
      paretoSum2 += hist[i]*(log(bucketCenter) - logMode);
    }
  }
  double alpha2 = nValidPixels2 / paretoSum2;

  ROS_WARN_STREAM("Alpha1: " << alpha << " Alpha2: " << alpha2);*/

  // Finally calculate the threshold to where we have paretoThresh_
  // fraction of the pixels
  return exp((alpha*logMode-log(paretoThreshold_)) / alpha);
}

// ------------ Start SpectralSaliency ------------
SpectralSaliency::~SpectralSaliency() {}

Mat_<double> SpectralSaliency::CalculateVisualUtility(
  const Mat& image, double time) {
  Mat_<double> retval;

  // Get a floating point grey version of the image
  /*Mat tmpGreyImage;
  if (image.channels() != 1) {
    cvtColor(image, tmpGreyImage, CV_BGR2GRAY);
  } else {
    tmpGreyImage = image;
  }
  Mat_<double> greyImage;
  tmpGreyImage.convertTo(greyImage, CV_64FC1, 1.0/255);
  Mat_<Vec<double, 2> > greyComplex;
  vector<Mat> greyGroup;
  greyGroup.push_back(greyImage);
  greyGroup.push_back(Mat_<double>::zeros(image.rows, image.cols));
  merge(greyGroup, greyComplex);

  Mat_<Vec<double, 2> > fftMat(image.rows, image.cols);
  dft(greyComplex, fftMat, DFT_COMPLEX_OUTPUT);

  vector<Mat> splitFftMat;
  split(fftMat, splitFftMat);

  Mat_<double> phaseMat;
  Mat_<double> logAmplitude;
  cartToPolar(splitFftMat[0], splitFftMat[1], logAmplitude, phaseMat);
  log(logAmplitude, logAmplitude);

  Mat_<double> spectralResidual;
  boxFilter(logAmplitude, spectralResidual, spectralResidual.depth(),
            Size(3, 3));
  spectralResidual = logAmplitude - spectralResidual;

  polarToCart(spectralResidual, phaseMat, splitFftMat[0], splitFftMat[1]);
  merge(splitFftMat, fftMat);

  Mat_<Vec<double, 2> > complexSaliency;
  dft(fftMat, complexSaliency, DFT_COMPLEX_OUTPUT | DFT_INVERSE);
  vector<Mat> splitSaliency;
  split(complexSaliency, splitSaliency);

  retval = splitSaliency[0].mul(splitSaliency[0]) +
    splitSaliency[1].mul(splitSaliency[1]);*/

  // The 32-bit floating point version to speed things up
  Mat tmpGreyImage;
  if (image.channels() != 1) {
    cvtColor(image, tmpGreyImage, CV_BGR2GRAY);
  } else {
    tmpGreyImage = image;
  }
  Mat_<float> greyImage;
  tmpGreyImage.convertTo(greyImage, CV_32FC1, 1.0/255);
  Mat_<Vec<float, 2> > greyComplex;
  vector<Mat> greyGroup;
  greyGroup.push_back(greyImage);
  greyGroup.push_back(Mat_<float>::zeros(image.rows, image.cols));
  merge(greyGroup, greyComplex);

  Mat_<Vec<float, 2> > fftMat(image.rows, image.cols);
  dft(greyComplex, fftMat, DFT_COMPLEX_OUTPUT);

  vector<Mat> splitFftMat;
  split(fftMat, splitFftMat);

  Mat_<float> phaseMat;
  Mat_<float> logAmplitude;
  cartToPolar(splitFftMat[0], splitFftMat[1], logAmplitude, phaseMat);
  log(logAmplitude, logAmplitude);

  Mat_<float> spectralResidual;
  boxFilter(logAmplitude, spectralResidual, spectralResidual.depth(),
            Size(3, 3));
  spectralResidual = logAmplitude - spectralResidual;

  polarToCart(spectralResidual, phaseMat, splitFftMat[0], splitFftMat[1]);
  merge(splitFftMat, fftMat);

  Mat_<Vec<float, 2> > complexSaliency;
  dft(fftMat, complexSaliency, DFT_COMPLEX_OUTPUT | DFT_INVERSE);
  vector<Mat> splitSaliency;
  split(complexSaliency, splitSaliency);

  retval = splitSaliency[0].mul(splitSaliency[0]) +
    splitSaliency[1].mul(splitSaliency[1]);

  return retval;
}

// ------- Start RelativeEntropyVUWrapper

RelativeEntropyVUWrapper::~RelativeEntropyVUWrapper() {}

bool RelativeEntropyVUWrapper::InitBoxCalculator(const cv::Mat& image,
                                                 double time) {
  // First get the visual utility of the entire image
  Mat_<double> baseVu = baseEstimator_->CalculateVisualUtility(image, time);

  // Now get the integral image so we can compute more quickly
  integralVu_.reset(new Mat_<double>());
  integral(baseVu, *integralVu_, CV_64F);

  return true;
}

double RelativeEntropyVUWrapper::CalculateVisualUtilityOfBox(int x, int y,
                                                             int h, int w) {
  const Mat_<double>& intImage = *integralVu_;

  double imArea = (intImage.rows-1)*(intImage.cols-1);
  double imSum = intImage[intImage.rows-1][intImage.cols-1];
  double pB = w*h / imArea;
  double rB = intImage[y][x] + intImage[y+h][x+w] -
    intImage[y][x+w] - intImage[y+h][x];
  double entropy = 0;
  if (imSum < 1e-10 || rB < 1e-10 || pB < 1e-10) {
    // We basically have a zero value, so force the entropy to be zero
  } else {
    rB /= imSum;
    if (rB > pB) {
      entropy = rB * log(rB/pB) + (1-rB) * log((1-rB)/(1-pB));
    } else {
      entropy = - pB * log(pB/rB) - (1-pB) * log((1-pB)/(1-rB));
    }
  }

  if (isnan(entropy)) {
    ROS_WARN_STREAM("Somehow we have the entropy being a NaN."
                    << " pB = " << pB
                    << " rB = " << rB
                    << " imSum = " << imSum);
  }

  return entropy;
}

// --------- Start LaplacianVU -------------
LaplacianVU::~LaplacianVU() {}

Mat_<double> LaplacianVU::CalculateVisualUtility(const cv::Mat& image,
                                                 double time) {
  Mat_<double> retval;

  Mat tmpGreyImage;
  if (image.channels() != 1) {
    cvtColor(image, tmpGreyImage, CV_BGR2GRAY);
  } else {
    tmpGreyImage = image;
  }
  Mat_<double> greyImage;
  tmpGreyImage.convertTo(greyImage, CV_64FC1, 1.0/255);

  Laplacian(greyImage, retval, CV_64FC1, ksize_);
  retval = abs(retval);

  return retval;
}

// --------- Start AverageCenterSurround ---------
CenterSurroundHistogram::~CenterSurroundHistogram() {}

CenterSurroundHistogram::CenterSurroundHistogram(
  const std::vector<double>& surroundScales,
  const std::string& distType)
  : surroundScales_(surroundScales) {
  if (distType == "chisq") {
    distType_ = CV_COMP_CHISQR;
  } else if (distType == "correl") {
    distType_ = CV_COMP_CORREL;
  } else if (distType == "intersect") {
    distType_ = CV_COMP_INTERSECT;
  } else if (distType == "bhattacharyya") {
    distType_ = CV_COMP_BHATTACHARYYA;
  } else {
    ROS_ERROR_STREAM("Invalid distance type: " << distType
                     << " defaulting to Chi Squared");
    distType_ = CV_COMP_CHISQR;
  }
}

Mat_<double> CenterSurroundHistogram::CalculateVisualUtility(const Mat& image,
                                                             double time) {
  ROS_FATAL("The visual utility for every pixel is not defined for this "
            "estimator.");
  return Mat_<double>();
}

bool CenterSurroundHistogram::InitBoxCalculator(const cv::Mat& image,
                                                double time) {
  // Get the image intensity since that's the feature we're going to use
  Mat tmpGreyImage;
  if (image.channels() != 1) {
    cvtColor(image, tmpGreyImage, CV_BGR2GRAY);
  } else {
    tmpGreyImage = image;
  }
  Mat_<uint8_t> greyImage(tmpGreyImage);

  // Calculate the integral histogram for the image
  integralHist_.reset(cv_utils::IntegralHistogram<int>::Calculate<uint8_t>(
    greyImage, 64, &std::pair<uint8_t, uint8_t>(0, 255)));

  return true;
}

double CenterSurroundHistogram::CalculateVisualUtilityOfBox(int x, int y,
                                                            int h, int w) {
  double bestScore = 0;
  for (vector<double>::const_iterator scaleI = surroundScales_.begin();
       scaleI != surroundScales_.end(); ++scaleI) {
    const double centerW = w * (*scaleI);
    const double centerH = h * (*scaleI);
    const int centerX1 = cvRound(x + (w - centerW) / 2.0);
    const int centerY1 = cvRound(y + (h - centerH) / 2.0);
    Mat_<float> centerHist =
      integralHist_->GetHistInRegion(Rect(centerX1, centerY1,
                                          cvRound(centerW), cvRound(centerH)));

    const double surW = centerW * M_SQRT2;
    const double surH = centerH * M_SQRT2;
    const int surX1 = cvRound(x + (w - surW) / 2.0);
    const int surY1 = cvRound(y + (h - surH) / 2.0);
    Mat_<float> surHist =
      integralHist_->GetHistInRegion(Rect(surX1, surY1,
                                          cvRound(surW), cvRound(surH)));
    surHist -= centerHist;

    // Normalize the histograms
    const int centerArea = cvRound(centerH) * cvRound(centerW);
    centerHist /= centerArea;
    surHist /= (cvRound(surW) * cvRound(surH) - centerArea);

    double score = compareHist(centerHist, surHist, distType_);
    if (score > bestScore) {
      bestScore = score;
    }
  }
  return bestScore;
}

// --------- Start Objectness ------------
Objectness::~Objectness() {}

Objectness::Objectness() : impl_(true) {
  if (!impl_.Init()) {
    ROS_FATAL_STREAM("Couldn't not initialize the objectness wrapper");
  }
}

void Objectness::CalculateVisualUtility(const cv::Mat& image,
                                        const std::vector<cv::Rect>& rois,
                                        double time,
                                        std::vector<ROIScore>* vuOut) {
  lastRuntime_.reset(new double(0));
  impl_.CalculateObjectness(image, rois, vuOut, lastRuntime_.get());
}

cv::Mat Objectness::CalculateVisualUtility(const cv::Mat& image,
                                           int minX, int minY,
                                           int minW, int minH,
                                           int strideX, int strideY,
                                           double strideW, double strideH,
                                           bool fixAspect,
                                           double time,
                                           const cv::Mat& mask) {
  Mat scores;

  vector<double> widths;
  vector<double> heights;
  GetGridHeightsAndWidths(image, minX, minY, minW, minH, strideW, strideH,
                          fixAspect, &widths, &heights);

  // Build the output score matrix
  InitializeScoreGrid(image, minX, minY, strideX, strideY, fixAspect,
                      widths, heights, &scores);
  ROS_ASSERT(mask.empty() ||
             (mask.dims == scores.dims &&
              mask.size == scores.size));

  // Build up the list of boxes to evaluate
  vector<Rect> rois;
  for (unsigned int widthI = 0u; widthI < widths.size(); ++widthI) {
    for (int curX = minX; curX < image.cols-widths[widthI];) {
      for (int curY = minY; curY < image.rows;) {
        if (fixAspect) {
          if (curY + heights[widthI] <= image.rows) {
            rois.push_back(Rect(curX, curY, widths[widthI], heights[widthI]));
          }
        } else {
          for (unsigned int heightI = 0u;
               heightI < heights.size() &&
                 curY + heights[heightI] <= image.rows;
               ++heightI) {
            rois.push_back(Rect(curX, curY, widths[widthI],
                                heights[heightI]));
          }
        }
        curY += strideY;
      }
      curX += strideX;
    }
  }

  // Do the evaluation
  vector<ROIScore> scoreList;
  CalculateVisualUtility(image, rois, time, &scoreList);

  // Now load the results into the output grid
  int gridIdx[4]; // (s, x, y) or (w, h, x, y)
  for (vector<ROIScore>::const_iterator scoreI = scoreList.begin();
       scoreI != scoreList.end(); ++scoreI) {
    gridIdx[0] = (log(scoreI->second.width) - log(minW)) / log(strideW);
    gridIdx[scores.dims-2] = (scoreI->second.x - minX) / strideX;
    gridIdx[scores.dims-1] = (scoreI->second.y - minY) / strideY;
    if (!fixAspect) {
      gridIdx[1] = (log(scoreI->second.height) - log(minH)) / log(strideH);
    }
    ROS_ASSERT(gridIdx[0] >= 0 && gridIdx[1] >= 0 && gridIdx[2] >= 0 &&
               gridIdx[0] < scores.size[0] &&
               gridIdx[1] < scores.size[1] &&
               gridIdx[2] < scores.size[2]);
    scores.at<double>(gridIdx) = scoreI->first;
  }

  return scores;
}

Mat_<double> Objectness::CalculateVisualUtility(const Mat& image,
                                                double time) {
  ROS_FATAL("Visual utility for a pixel is not defined");
  return Mat_<double>::zeros(image.rows, image.cols);
}

// ---------- Start ROSBag ---------------
ROSBag::ResultKey::ResultKey(const std::string& _filename,
                             const cv::Rect _rect)
  : filenameHash(hash<string>()(_filename)), rect(_rect) {}
size_t ROSBag::ResultKeyHash::operator()(const ResultKey& s) const {
  size_t result = s.filenameHash;
  hash_combine(result, hash_value(s.rect));
  return result;
}

ROSBag::ROSBag(const string& filename) {
  rosbag::Bag bag;
  bag.open(filename, rosbag::bagmode::Read);

  CreateBaseEstimator(bag);

  LoadBagResults(bag);

  bag.close();
}

ROSBag::~ROSBag() {}

void ROSBag::CreateBaseEstimator(const rosbag::Bag& bag) {

  // Load all the parameters into ros params
  ros::NodeHandle handle("~ROSBag");
  rosbag::View view(bag, rosbag::TopicQuery("parameters"));
  BOOST_FOREACH(rosbag::MessageInstance const msg, view) {
    Parameter::ConstPtr param = msg.instantiate<Parameter>();
    if (param != NULL) {
      handle.setParam(param->name.data, param->value.data);
    }
  }

  // Create the visual utility estimator
  transformEstimator_.reset(CreateTransformEstimator(handle));
  baseEstimator_.reset(CreateVisualUtilityEstimator(handle,
                                                    *transformEstimator_));

  // Delete all the parameters
  rosbag::View view2(bag, rosbag::TopicQuery("parameters"));
  BOOST_FOREACH(rosbag::MessageInstance const msg, view2) {
    Parameter::ConstPtr param = msg.instantiate<Parameter>();
    if (param != NULL) {
      handle.deleteParam(param->name.data);
    }
  }
}

void ROSBag::LoadBagResults(const rosbag::Bag& bag) {
  rosbag::View view(bag, rosbag::TopicQuery("results"));
  BOOST_FOREACH(rosbag::MessageInstance const msg, view) {
    VisualUtilityEstimation::ConstPtr result =
      msg.instantiate<VisualUtilityEstimation>();
    if (result != NULL) {
      if (result->regions.size() != result->scores.size()) {
        ROS_ERROR_STREAM("The number of regions and scores don't match. "
                         "Aborting");
        continue;
      }
      for (unsigned int i = 0u; i < result->regions.size(); ++i) {
        const sensor_msgs::RegionOfInterest& region = result->regions[i];
        lut_[ResultKey(result->image, Rect(region.x_offset, region.y_offset,
                                           region.width, region.height))] =
          result->scores[i];
      }
    }
  }
}

void ROSBag::CalculateVisualUtility(const cv::Mat& image,
                                    const std::vector<cv::Rect>& rois,
                                    double time,
                                    std::vector<ROIScore>* vuOut) {
  if (baseEstimator_.get()) {
    baseEstimator_->CalculateVisualUtility(image, rois, time, vuOut);
  }
}

cv::Mat_<double> ROSBag::CalculateVisualUtility(const cv::Mat& image,
                                                double time) {
  if (baseEstimator_.get()) {
    return baseEstimator_->CalculateVisualUtility(image, time);
  }
  return Mat_<double>::zeros(image.rows, image.cols);
}

void ROSBag::CalculateVisualUtility(const std::string& filename,
                                    const std::vector<cv::Rect>& rois,
                                    double time,
                                    std::vector<ROIScore>* vuOut) {
  ROS_ASSERT(vuOut);

  // Go through all the rois and look them up in the lookup table.
  for (vector<Rect>::const_iterator roi = rois.begin(); roi != rois.end();
       ++roi) {
    hash_map<ResultKey, float, ResultKeyHash>::const_iterator entry =
      lut_.find(ResultKey(filename, *roi));
    if (entry != lut_.end()) {
      vuOut->push_back(ROIScore(entry->second, *roi));
    } else {
      vuOut->push_back(ROIScore(0.0, *roi));
    }
  }

  if (vuOut->size() != rois.size()) {
    ROS_ERROR_STREAM("We could not find entries in the LUT for all of the "
                     "rois. "
                     << rois.size() - vuOut->size()
                     << " entries were missing for file: "
                     << filename);
  }
}

// ---------- Start HOGDetector ---------------
HOGDetector::~HOGDetector() {}

HOGDetector::HOGDetector(const std::string& modelFile,
                         bool useDefaultPeopleDetector,
                         Size winStride,
                         bool doCache) {
  if (!impl_.InitModel(modelFile, useDefaultPeopleDetector,
                       -numeric_limits<double>::infinity(), // threshold
                       false, // doNMS
                       winStride,
                       doCache)) {
    ROS_FATAL_STREAM("Could not initialize HOG detector");
  }
}

void HOGDetector::CalculateVisualUtility(const cv::Mat& image,
                                         const std::vector<cv::Rect>& rois,
                                         double time,
                                         std::vector<ROIScore>* vuOut) {
  ROS_ASSERT(vuOut);

  vector<double> scores;
  vector<Rect> foundLocations;
  lastRuntime_.reset(new double(0));
  impl_.DetectObjects(image, rois, &foundLocations, &scores,
                       lastRuntime_.get());

  ROS_ASSERT(scores.size() == foundLocations.size());

  for (unsigned int i = 0u; i < foundLocations.size(); ++i) {
    vuOut->push_back(ROIScore(scores[i], foundLocations[i]));
  }
}

Mat_<double> HOGDetector::CalculateVisualUtility(const Mat& image,
                                                 double time) {
  ROS_FATAL("The visual utility for every pixel is not defined for this "
            "estimator.");
  return Mat_<double>();
}

// ---------- Start CascadeDetector ---------------
CascadeDetector::~CascadeDetector() {}
CascadeDetector::CascadeDetector(const std::string& modelFile){
  if (!impl_.Init(modelFile)) {
    ROS_FATAL_STREAM("Could not load the classifier defined in " << modelFile);
  }
}

Mat_<double> CascadeDetector::CalculateVisualUtility(const Mat& image,
                                                 double time) {
  ROS_FATAL("The visual utility for every pixel is not defined for this "
            "estimator.");
  return Mat_<double>();
}

void CascadeDetector::CalculateVisualUtility(
  const cv::Mat& image,
  const std::vector<cv::Rect>& rois,
  double time,
  std::vector<ROIScore>* vuOut) {

  ROS_ASSERT(vuOut);

  if (image.empty()) {
    return;
  }

  vector<int> scores;
  vector<Rect> foundLocations;
  lastRuntime_.reset(new double(0));
  impl_.DetectObjects(image, rois, &foundLocations, &scores,
                      lastRuntime_.get());

  ROS_ASSERT(scores.size() == rois.size());
  for (unsigned int i = 0u; i < scores.size(); ++i) {
    vuOut->push_back(ROIScore(scores[i], rois[i]));
  }
}

// ----------- Start ScaledDetectorWrapper -----------
ScaledDetectorWrapper::~ScaledDetectorWrapper() {}

bool ScaledDetectorWrapper::InitBoxCalculator(const cv::Mat& image,
                                              double time) {
  ros::WallTime startTime = ros::WallTime::now();

  // Resize the image and send it to the base estimator
  Mat scaledImage;
  cv::resize(image, scaledImage, cv::Size(), scaleFactor_, scaleFactor_);

  resizeTime_ = ros::WallTime::now() - startTime;

  return baseEstimator_->InitBoxCalculator(scaledImage, time);
}

double ScaledDetectorWrapper::CalculateVisualUtilityOfBox(int x, int y,
                                                          int h, int w) {
  // Scale the coordinates of the box and send to the base estimaor
  return baseEstimator_->CalculateVisualUtilityOfBox(
    cvRound(x * scaleFactor_),
    cvRound(y * scaleFactor_),
    cvRound(h * scaleFactor_),
    cvRound(w * scaleFactor_));
}

void ScaledDetectorWrapper::CalculateVisualUtility(
  const cv::Mat& image,
  const std::vector<cv::Rect>& rois,
  double time,
  std::vector<ROIScore>* vuOut) {
  ROS_ASSERT(vuOut);

  // Scale the input rois
  vector<Rect> scaledRois;
  unordered_map<Rect, const Rect*> roiMap;
  for (vector<Rect>::const_iterator roiI = rois.begin();
       roiI != rois.end();
       ++roiI) {
    scaledRois.push_back(Rect(cvRound(roiI->x * scaleFactor_),
                              cvRound(roiI->y * scaleFactor_),
                              cvRound(roiI->width * scaleFactor_),
                              cvRound(roiI->height * scaleFactor_)));
    roiMap[scaledRois.back()] = &(*roiI);
  }

  ros::WallTime startTime = ros::WallTime::now();

  // Resize the image
  Mat scaledImage;
  cv::resize(image, scaledImage, cv::Size(), scaleFactor_, scaleFactor_);
  resizeTime_ = ros::WallTime::now() - startTime;

  // Calculate the visual utility
  vector<ROIScore> scaledScores;
  startTime = ros::WallTime::now();
  baseEstimator_->CalculateVisualUtility(scaledImage,
                                         scaledRois,
                                         time,
                                         &scaledScores);
  ros::WallDuration baseTime = ros::WallTime::now() - startTime;

  // Scale the output rois
  for (vector<ROIScore>::const_iterator scoreI = scaledScores.begin();
       scoreI != scaledScores.end();
       ++scoreI) {
    vuOut->push_back(ROIScore(scoreI->first,
                              *roiMap[scoreI->second]));
  }

  // Do the timing properly
  lastRuntime_.reset(new double(0));
  *lastRuntime_ += resizeTime_.toSec();
  if (baseEstimator_->GetLastRuntime()) {
    *lastRuntime_ += *baseEstimator_->GetLastRuntime();
  } else {
    *lastRuntime_ += baseTime.toSec();
  }

}

cv::Mat_<double> ScaledDetectorWrapper::CalculateVisualUtility(
  const cv::Mat& image,
  double time) {
  ros::WallTime startTime = ros::WallTime::now();

  // Rescale the image
  Mat scaledImage;
  cv::resize(image, scaledImage, cv::Size(), scaleFactor_, scaleFactor_);

  ros::WallDuration resizeTime = ros::WallTime::now() - startTime;
  startTime = ros::WallTime::now();

  // Calculate the visual utility on the scaled image
  Mat_<double> scaledVU = baseEstimator_->CalculateVisualUtility(
    scaledImage, time);

  Mat_<double> retval;
  cv::resize(scaledVU, retval, image.size());

  ros::WallDuration baseTime = ros::WallTime::now() - startTime;

  // Store the timing data properly
  lastRuntime_.reset(new double(0));
  *lastRuntime_ += resizeTime.toSec();
  if (baseEstimator_->GetLastRuntime()) {
    *lastRuntime_ += *baseEstimator_->GetLastRuntime();
  } else {
    *lastRuntime_ += baseTime.toSec();
  }
  return retval;
}

// ----------- Start IntegralHOGDetector -----------
IntegralHOGDetector::IntegralHOGDetector(const std::string& modelFile,
                                         const cv::Size& winStride)
  : impl_(modelFile, winStride), hist_(), histSum_() {}

IntegralHOGDetector::~IntegralHOGDetector() {}

bool IntegralHOGDetector::InitBoxCalculator(const cv::Mat& image,
                                            double time) {
  hist_.reset(impl_.ComputeGradientIntegralHistograms(image, &histSum_));

  return true;
}

double IntegralHOGDetector::CalculateVisualUtilityOfBox(int x, int y, int h,
                                                        int w) {
  return impl_.ComputeScore(*hist_, histSum_, Rect(x, y, w, h));
}

cv::Mat_<double> IntegralHOGDetector::CalculateVisualUtility(
  const cv::Mat& image,
  double time) {
  ROS_FATAL("Per pixel evaluation is not implemented for this estimator");
  ROS_ASSERT(false);
  return cv::Mat_<double>();
}

// ----------- Start IntegralHOGCascade -----------
IntegralHOGCascade::IntegralHOGCascade(const std::string& modelFile,
                                        const cv::Size& winStride)
  : impl_(modelFile, winStride), hist_(), histSum_() {}

IntegralHOGCascade::~IntegralHOGCascade() {}

bool IntegralHOGCascade::InitBoxCalculator(const cv::Mat& image,
                                           double time) {
  hist_.reset(impl_.ComputeGradientIntegralHistograms(image, &histSum_));

  return true;
}

double IntegralHOGCascade::CalculateVisualUtilityOfBox(int x, int y, int h,
                                                       int w) {
  return impl_.ComputeScore(*hist_, histSum_, Rect(x, y, w, h));
}

cv::Mat_<double> IntegralHOGCascade::CalculateVisualUtility(
  const cv::Mat& image,
  double time) {
  ROS_FATAL("Per pixel evaluation is not implemented for this estimator");
  ROS_ASSERT(false);
  return cv::Mat_<double>();
}

} // namespace

ext: cc


text:
//
//  short_message_db.cpp
//  ICBCPlatform
//
//  Created by Alex on 11/27/14.
//  Copyright (c) 2014 BiFang technology. All rights reserved.
//
#include "algorithm.hpp"
#include "short_message_db.h"
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include "logger.hpp"

short_message_db::short_message_db(const std::string& filename)
{
	boost::filesystem::path rootpath = boost::filesystem::initial_path<boost::filesystem::path>();
	boost::filesystem::path databasepath = rootpath / "database";
	databasepath += boost::filesystem::path::preferred_separator;
	if(!boost::filesystem::exists(databasepath))
	{
		try
		{
			boost::filesystem::create_directory(databasepath);
		}
		catch (std::exception& ex)
		{
			logger_log(__FUNCTION__, LEVEL_ERROR,"exception: %s.", ex.what());
		}
	}
	filename_ = databasepath.string()  + filename;

	table_ = "sm_table";

	item_company_account_ = "company_account";
	item_subaccount_ = "subaccount";
	item_session_id_ = "session_id";
	item_sn_ = "sn";
	item_message_id_ = "msg_id";
	item_src_addr_ = "src_addr";
	item_dst_addr_ = "dst_addr";
	item_submit_time_ = "submit_time";
	item_delivering_time_ = "delivering_time";
	item_delivery_time_ = "delivery_time";
	item_datacoding_ = "datacoding";
	item_hash_ = "hash";
	item_msg_ = "msg";
	item_error_status_ = "error_status";
	item_error_code_ = "error_code";
	item_udhi_reference_ = "udhi_reference";
	item_udhi_total_parts_ = "udhi_total_parts";
	item_udhi_part_index_ = "udhi_part_index";

	std::string create_table_sql = "create table if not exists ";
	std::string v1 = " VARCHAR(32) ";
	std::string v2 = " VARCHAR(1024) ";
	std::string v3 = " VARCHAR(8) ";
	int status;

	if(!boost::filesystem::exists(filename_))
	{
		sqlite3pp::database db(filename_.c_str());
		try
		{
			create_table_sql = create_table_sql + table_ + "(" + item_company_account_ + v1 + " , ";
			create_table_sql = create_table_sql + item_subaccount_   + v1 + ", ";
			create_table_sql = create_table_sql + item_session_id_   + v1 + ", ";
			create_table_sql = create_table_sql + item_sn_   + v1 + ", ";
			create_table_sql = create_table_sql + item_message_id_   + v1 + ", ";
			create_table_sql = create_table_sql + item_src_addr_   + v1 + ", ";
			create_table_sql = create_table_sql + item_dst_addr_   + v1 + ", ";
			create_table_sql = create_table_sql + item_submit_time_   + v1 + ", ";
			create_table_sql = create_table_sql + item_delivering_time_   + v1 + ", ";
			create_table_sql = create_table_sql + item_delivery_time_   + v1 + ", ";
			create_table_sql = create_table_sql + item_datacoding_   + v3 + ", ";
			create_table_sql = create_table_sql + item_hash_   + v1 + ", ";
			create_table_sql = create_table_sql + item_msg_   + v2 + ", ";
			create_table_sql = create_table_sql + item_error_code_   + v1 + ", ";
			create_table_sql = create_table_sql + item_error_status_   + v1 + ", ";
			create_table_sql = create_table_sql + item_udhi_reference_   + v3 + ", ";
			create_table_sql = create_table_sql + item_udhi_total_parts_   + v3 + ", ";
			create_table_sql = create_table_sql + item_udhi_part_index_   + v3 + ") ";
			status = db.execute(create_table_sql.c_str());
			if(status != 0)
			{
				logger_log(__FUNCTION__, LEVEL_ERROR, "create table %s failed, db is %s , status is: %d " ,
						   table_.c_str() , filename_.c_str(), status);
			}
			/*
			status = db.execute("PRAGMA synchronous = OFF");
			status = db.execute("PRAGMA journal_mode = MEMORY");
			if(status != 0)
			{
				logger_log(__FUNCTION__, LEVEL_ERROR, "set \"synchronous = OFF\" of db %s failed, status is: %d " , filename_.c_str(), status);
			}
			*/
		}
		catch (std::exception& ex)
		{
			std::string what = ex.what();
			logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		}
	}
}

bool short_message_db::insert(const std::vector<cb_sm_information>& smis)
{
	try
	{
		WORK_START
		sqlite3pp::database db(filename_.c_str());
		sqlite3pp::transaction xct(db);

		std::string insert_default_sql = "INSERT INTO " + table_ + " ( "
		+ item_company_account_ + "," + item_subaccount_ + ","+ item_session_id_  + "," + item_sn_  + "," + item_message_id_ + "," + item_src_addr_ + ","+ item_dst_addr_ + ","+ item_submit_time_ + "," + item_delivering_time_ + ","+ item_delivery_time_ +   ","+ item_datacoding_  + ","+ item_hash_ + ","+ item_msg_  + ","+ item_error_code_  + "," + item_error_status_ + ","+ item_udhi_reference_  + "," + item_udhi_total_parts_ + "," + item_udhi_part_index_ + ")  VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
		int status;
		for(size_t i = 0; i < smis.size(); i++)
		{
			sqlite3pp::command cmd(db,  insert_default_sql.c_str());
			cmd.bind(1, smis.at(i).company_account.c_str());
			cmd.bind(2, smis.at(i).systemid.c_str());
			cmd.bind(3, smis.at(i).session_id.c_str());
			cmd.bind(4, (int)smis.at(i).sn_by_client);
			cmd.bind(5, smis.at(i).message_id_of_protocol_server.c_str());
			cmd.bind(6, smis.at(i).src_addr.c_str());
			cmd.bind(7, smis.at(i).dst_addr.c_str());
			cmd.bind(8, (long long int)smis.at(i).submit_time_of_client);
			cmd.bind(9, (long long int)smis.at(i).delivering_time_of_client);
			cmd.bind(10, (long long int)smis.at(i).delivery_time_of_client);
			cmd.bind(11, (int)smis.at(i).datacoding_type);
			cmd.bind(12, smis.at(i).content_hash.c_str());
			cmd.bind(13, smis.at(i).content.c_str());
			cmd.bind(14, (int)smis.at(i).error_code);
			cmd.bind(15, smis.at(i).error_status.c_str());
			cmd.bind(16, (int)smis.at(i).udhi_reference);
			cmd.bind(17, (int)smis.at(i).udhi_total_parts);
			cmd.bind(18, (int)smis.at(i).udhi_part_index);

			status = cmd.execute();
			if(status != 0)
			{
				logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error, execute returns %d ." , status);
			}
		}

		status = xct.commit();
		if(status != 0)
		{
			logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error, commit returns %d ." , status);
			return false;
		}
		char msg[1024];
		sprintf(msg, "insert %d smis to %s", (int)smis.size(), filename_.c_str());
		WORK_FINISH(msg)
		return true;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}
bool short_message_db::read_smi(sqlite3pp::query::iterator& i, cb_sm_information& smi)
{
	smi.company_account = (*i).get< char const*>(0);
	smi.systemid = (*i).get< char const*>(1);
	smi.session_id = (*i).get< char const*>(2);
	smi.sn_by_client = (unsigned int)(*i).get< int>(3);
	smi.message_id_of_protocol_server = (*i).get< char const*>(4);
	smi.src_addr = (*i).get< char const*>(5);
	smi.dst_addr = (*i).get< char const*>(6);
	smi.submit_time_of_client = (boost::uint64_t)(*i).get< long long int>(7);
	smi.delivering_time_of_client = (boost::uint64_t)(*i).get< long long int>(8);
	smi.delivery_time_of_client = (boost::uint64_t)(*i).get< long long int>(9);
	smi.datacoding_type = (unsigned char)(*i).get< int>(10);
	smi.content_hash = (*i).get< char const*>(11);
	smi.content = (*i).get< char const*>(12);
	smi.error_code = (*i).get< int>(13);
	smi.error_status = (*i).get< char const*>(14);
	smi.udhi_reference = (unsigned char)(*i).get< int>(15);
	smi.udhi_total_parts = (unsigned char)(*i).get< int>(16);
	smi.udhi_part_index = (unsigned char)(*i).get< int>(17);
	return true;
}

bool short_message_db::get(std::vector<cb_sm_information>& smis, const std::vector<sm_db_pair> &get_decide_pairs, const std::vector<std::string>& delete_decide_items)
{
	try
	{
		WORK_START
		{
			sqlite3pp::database db(filename_.c_str());
			std::string qry_sql = "SELECT * FROM "+ table_;
			size_t index = 0;
			for(index = 0; index < get_decide_pairs.size(); index++)
			{
				if(index == 0)
				{
					qry_sql += " WHERE ";
				}
				if(index > 0)
				{
					qry_sql += " and ";
				}
				qry_sql = qry_sql + get_decide_pairs.at(index).key + "='" + get_decide_pairs.at(index).value + "' ";
			}

			sqlite3pp::query qry(db,  qry_sql.c_str());
			sqlite3pp::query::iterator i = qry.begin();
			if(i == qry.end())
			{
				return false;
			}
			for (; i != qry.end(); ++i)
			{
				cb_sm_information smi;
				read_smi(i, smi);
				smis.push_back(smi);
			}
			if(smis.size() == 0)
			{
				return true;
			}
		}
		bool deleted = false;
		{
			size_t index = 0;
			std::vector< std::vector<sm_db_pair> > v_pairs;
			for(index = 0; index < smis.size(); index++)
			{
				std::vector<sm_db_pair> pairs;
				for(size_t j = 0; j < delete_decide_items.size(); j++)
				{
					sm_db_pair pair;
					pair.key = delete_decide_items.at(j);
					pair.value = get_value(smis.at(index), pair.key);
					pairs.push_back(pair);
				}
				v_pairs.push_back(pairs);
			}
			deleted = delete_internal(v_pairs);
		}
		char msg[1024];
		sprintf(msg, "get %d smis and delete thme of %s", (int)smis.size(), filename_.c_str());
		WORK_FINISH(msg)
		return deleted;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}
bool short_message_db::get(int max_get, std::vector<cb_sm_information>& smis, const std::vector<sm_db_pair> &get_decide_pairs, const std::vector<std::string>& delete_decide_items)
{
	try
	{
		WORK_START
		{
			sqlite3pp::database db(filename_.c_str());
			std::string qry_sql = "SELECT * FROM "+ table_;
			size_t index = 0;
			for(index = 0; index < get_decide_pairs.size(); index++)
			{
				if(index == 0)
				{
					qry_sql += " WHERE ";
				}
				if(index > 0)
				{
					qry_sql += " and ";
				}
				qry_sql = qry_sql + get_decide_pairs.at(index).key + "='" + get_decide_pairs.at(index).value + "' ";
			}
			qry_sql = qry_sql + " LIMIT " + format_decimal_to_string((unsigned int)max_get);
			sqlite3pp::query qry(db,  qry_sql.c_str());
			sqlite3pp::query::iterator i = qry.begin();
			if(i == qry.end())
			{
				return false;
			}
			for (; i != qry.end(); ++i)
			{
				cb_sm_information smi;
				read_smi(i, smi);
				smis.push_back(smi);
			}
			if(smis.size() == 0)
			{
				return true;
			}
		}
		bool deleted = false;
		{
			size_t index = 0;
			std::vector< std::vector<sm_db_pair> > v_pairs;
			for(index = 0; index < smis.size(); index++)
			{
				std::vector<sm_db_pair> pairs;
				for(size_t j = 0; j < delete_decide_items.size(); j++)
				{
					sm_db_pair pair;
					pair.key = delete_decide_items.at(j);
					pair.value = get_value(smis.at(index), pair.key);
					pairs.push_back(pair);
				}
				v_pairs.push_back(pairs);
			}
			deleted = delete_internal(v_pairs);
		}
		char msg[1024];
		sprintf(msg, "get %d smis and delete them of %s ", (int)smis.size(), filename_.c_str());
		WORK_FINISH(msg)
		return deleted;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}
bool short_message_db::get_submit_time_before(boost::uint64_t submit_time, std::vector<cb_sm_information>& smis, const std::vector<std::string>& delete_decide_items)
{
	try
	{
		WORK_START
		{
			sqlite3pp::database db(filename_.c_str());
			std::string qry_sql = "SELECT * FROM "+ table_;
			qry_sql += " WHERE ";
			qry_sql = qry_sql + item_submit_time_ + " < " + datatype_convert<std::string>(submit_time) + " ";

			sqlite3pp::query qry(db,  qry_sql.c_str());
			sqlite3pp::query::iterator i = qry.begin();
			if(i == qry.end())
			{
				return false;
			}
			for (; i != qry.end(); ++i)
			{
				cb_sm_information smi;
				read_smi(i, smi);
				smis.push_back(smi);
			}
		}
		bool deleted = false;
		{
			size_t index = 0;
			std::vector< std::vector<sm_db_pair> > v_pairs;
			for(index = 0; index < smis.size(); index++)
			{
				std::vector<sm_db_pair> pairs;
				for(size_t j = 0; j < delete_decide_items.size(); j++)
				{
					sm_db_pair pair;
					pair.key = delete_decide_items.at(j);
					pair.value = get_value(smis.at(index), pair.key);
					pairs.push_back(pair);
				}
				v_pairs.push_back(pairs);
			}
			deleted = delete_internal(v_pairs);
		}
		char msg[1024];
		sprintf(msg, "get %d smis and delete them of %s ", (int)smis.size(), filename_.c_str());
		WORK_FINISH(msg)
		return deleted;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}
bool short_message_db::query_submit_time_between(boost::uint64_t begin_time, boost::uint64_t end_time, std::vector<cb_sm_information>& smis, const std::vector<sm_db_pair> &query_decide_pairs)
{
	try
	{
		WORK_START
		{
			sqlite3pp::database db(filename_.c_str());
			std::string qry_sql = "SELECT * FROM "+ table_;
			qry_sql += " WHERE ";
			for(size_t index = 0; index < query_decide_pairs.size(); index++)
			{
				if(index > 0)
				{
					qry_sql += " AND ";
				}
				qry_sql = qry_sql + query_decide_pairs.at(index).key + "='" + query_decide_pairs.at(index).value + "' ";
			}
			if(query_decide_pairs.size() > 0)
			{
				qry_sql += " AND ";
			}
			qry_sql = qry_sql + item_delivery_time_ + " > " + datatype_convert<std::string>(begin_time) + " ";
			qry_sql += " AND ";
			qry_sql = qry_sql + item_delivery_time_ + " < " + datatype_convert<std::string>(end_time) + " ";

			sqlite3pp::query qry(db,  qry_sql.c_str());
			sqlite3pp::query::iterator i = qry.begin();
			if(i == qry.end())
			{
				return false;
			}
			for (; i != qry.end(); ++i)
			{
				cb_sm_information smi;
				read_smi(i, smi);
				smis.push_back(smi);
			}
		}

		char msg[1024];
		sprintf(msg, "query %d smis of %s ", (int)smis.size(), filename_.c_str());
		WORK_FINISH(msg)
		return true;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}
std::string short_message_db::get_value(const cb_sm_information& smi, const std::string& item_name)
{
	if(item_name.compare(item_company_account_) == 0)
	{
		return smi.company_account;
	}
	else if(item_name.compare(item_subaccount_) == 0)
	{
		return smi.systemid;
	}
	else if(item_name.compare(item_sn_) == 0)
	{
		return datatype_convert<std::string>(smi.sn_by_client);
	}
	else if(item_name.compare(item_message_id_) == 0)
	{
		return smi.message_id_of_protocol_server;
	}
	else if(item_name.compare(item_src_addr_) == 0)
	{
		return smi.src_addr;
	}
	else if(item_name.compare(item_dst_addr_) == 0)
	{
		return smi.dst_addr;
	}
	else if(item_name.compare(item_submit_time_) == 0)
	{
		return datatype_convert<std::string>(smi.submit_time_of_client);
	}
	else if(item_name.compare(item_delivering_time_) == 0)
	{
		return datatype_convert<std::string>(smi.delivering_time_of_client);
	}
	else if(item_name.compare(item_delivery_time_) == 0)
	{
		return datatype_convert<std::string>(smi.delivery_time_of_client);
	}
	else if(item_name.compare(item_datacoding_) == 0)
	{
		return datatype_convert<std::string>((int)smi.datacoding_type);
	}
	else if(item_name.compare(item_hash_) == 0)
	{
		return smi.content_hash;
	}
	else if(item_name.compare(item_msg_) == 0)
	{
		return smi.content;
	}
	else if(item_name.compare(item_error_code_) == 0)
	{
		return datatype_convert<std::string>(smi.error_code);
	}
	else if(item_name.compare(item_error_status_) == 0)
	{
		return smi.error_status;
	}
	else if(item_name.compare(item_session_id_) == 0)
	{
		return smi.session_id;
	}
	return "";
}
bool short_message_db::delete_internal(const std::vector<sm_db_pair>& delete_decide_pairs)
{
	try
	{
		sqlite3pp::database db(filename_.c_str());
		std::string delete_sql = "DELETE FROM "+ table_ + " WHERE ";
		for(size_t i = 0; i < delete_decide_pairs.size(); i++)
		{
			if(i > 0)
			{
				delete_sql += " AND ";
			}
			delete_sql = delete_sql + delete_decide_pairs.at(i).key + "='" + delete_decide_pairs.at(i).value + "' ";
		}
		sqlite3pp::command cmd(db,  delete_sql.c_str());
		int status = db.execute(delete_sql.c_str() );

		if(status != 0)
		{
			logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error, execute returns %d ." , status);
			return  false;
		}
		return true;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}

bool short_message_db::delete_internal(const std::vector< std::vector<sm_db_pair> >& v_pairs)
{
	try
	{
		WORK_START
		sqlite3pp::database db(filename_.c_str());
		sqlite3pp::transaction xct(db);
		int status;
		for(size_t i = 0; i < v_pairs.size(); i++)
		{
			std::string delete_sql = "DELETE FROM "+ table_ + " WHERE ";
			std::vector<sm_db_pair> delete_decide_pairs = v_pairs.at(i);
			for(size_t i = 0; i < delete_decide_pairs.size(); i++)
			{
				if(i > 0)
				{
					delete_sql += " AND ";
				}
				delete_sql = delete_sql + delete_decide_pairs.at(i).key + "='" + delete_decide_pairs.at(i).value + "' ";
			}
			sqlite3pp::command cmd(db,  delete_sql.c_str());
			status = db.execute(delete_sql.c_str() );

			if(status != 0)
			{
				logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error, execute returns %d ." , status);
			}
		}
		status = xct.commit();
		if(status != 0)
		{
			logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error, commit returns %d ." , status);
			return false;
		}
		char msg[1024];
		sprintf(msg, "delete %d smis of %s ", (int)v_pairs.size(), filename_.c_str());
		WORK_FINISH(msg)
		return true;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}
bool short_message_db::update_internal(const std::vector<sm_db_pair>& update_decide_pairs, const std::vector<sm_db_pair>& update_pairs)
{
	try
	{
		sqlite3pp::database db(filename_.c_str());
		std::string update_sql = "UPDATE " + table_ + " SET ";

		//std::string delete_sql = "DELETE FROM "+ table_ + " WHERE ";
		for(size_t i = 0; i < update_pairs.size(); i++)
		{
			if(i > 0)
			{
				update_sql += " , ";
			}
			update_sql = update_sql + update_pairs.at(i).key + "='" + update_pairs.at(i).value + "' ";
		}
		update_sql += " WHERE ";
		for(size_t j = 0; j < update_decide_pairs.size(); j++)
		{
			if(j > 0)
			{
				update_sql += " AND ";
			}
			update_sql = update_sql + update_decide_pairs.at(j).key + "='" + update_decide_pairs.at(j).value + "' ";
		}
		sqlite3pp::command cmd(db,  update_sql.c_str());
		int status = db.execute(update_sql.c_str() );

		if(status != 0)
		{
			logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error, execute returns %d ." , status);
			return  false;
		}
		return true;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}

bool short_message_db::fetch_first_and_update(cb_sm_information& smi, const std::vector<sm_db_pair> &fetch_decide_pairs, const std::vector<std::string> &update_decide_items, const std::vector<sm_db_pair> &update_pairs)
{
	try
	{
		WORK_START
		{
			sqlite3pp::database db(filename_.c_str());
			std::string qry_sql = "SELECT * FROM "+ table_ ;
			for(size_t i = 0; i < fetch_decide_pairs.size(); i++)
			{
				if(i == 0)
				{
					qry_sql += " WHERE ";
				}
				if(i > 0)
				{
					qry_sql += " AND ";
				}
				qry_sql = qry_sql + fetch_decide_pairs.at(i).key + "='" + fetch_decide_pairs.at(i).value + "' ";
			}
			qry_sql = qry_sql + " LIMIT 1 ";
			sqlite3pp::query qry1(db,  qry_sql.c_str());
			sqlite3pp::query::iterator i = qry1.begin();
			if(i == qry1.end())
			{
				return false;
			}
			for (; i != qry1.end(); ++i)
			{
				read_smi(i, smi);
				break;
			}
		}
		bool updated = false;
		{
			std::vector<sm_db_pair> update_decide_pairs;
			for(size_t i = 0; i < update_decide_items.size(); i++)
			{
				sm_db_pair pair;
				pair.key = update_decide_items.at(i);
				pair.value = get_value(smi, pair.key);
				update_decide_pairs.push_back(pair);
			}
			updated = update_internal(update_decide_pairs, update_pairs);
		}
		char msg[1024];
		sprintf(msg, "fetch first smi and update it of %s", filename_.c_str());
		WORK_FINISH(msg)
		return updated;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}

bool short_message_db::delete_items(const std::vector<sm_db_pair> &delete_decide_pairs)
{
	return delete_internal(delete_decide_pairs);
}
bool short_message_db::read_all(std::vector<cb_sm_information> &smis)
{
	try
	{
		sqlite3pp::database db(filename_.c_str());
		std::string qry_sql = "SELECT * FROM "+ table_;

		sqlite3pp::query qry(db,  qry_sql.c_str());
		sqlite3pp::query::iterator i = qry.begin();
		if(i == qry.end())
		{
			return false;
		}
		for (; i != qry.end(); ++i)
		{
			cb_sm_information smi;
			read_smi(i, smi);
			smis.push_back(smi);
		}
		return true;
	}
	catch (std::exception& ex)
	{
		std::string what = ex.what();
		logger_log(__FUNCTION__, LEVEL_ERROR, "sqlite3 error: %s ." , what.c_str());
		return false;
	}
}

bool short_message_db::update(const std::vector<sm_db_pair> &update_decide_pairs, const std::vector<sm_db_pair> &update_pairs)
{
	return update_internal(update_decide_pairs, update_pairs);
}

max_stars_repo_name: dotphoenix/smppserver

max_issues_repo_name: dotphoenix/smppserver

max_forks_repo_name: dotphoenix/smppserver


text:
#include <iostream>
#include <gtest/gtest.h>
#include "../frame_transforms.h"
#include <boost/math/constants/constants.hpp>

using namespace snark::frame_transforms;

TEST(transforms, dh_to_matrix)
{
    dh_transform T_dh;
    T_dh.alpha=1;
    T_dh.r=1;
    T_dh.theta=boost::math::constants::pi<double>()/6;
    T_dh.alpha=-boost::math::constants::pi<double>()/2;
    EXPECT_LT((dh_to_matrix(T_dh)-(Eigen::Matrix4d()<<0.866025,0,-0.5,0.866025,0.5,0,0.866025,0.5,0,-1,0,0,0,0,0,1).finished()).norm(),1e-2);

}

TEST(transforms, dh_to_tr)
{
    dh_transform T_dh;
    T_dh.alpha=1;
    T_dh.r=1;
    T_dh.theta=boost::math::constants::pi<double>()/6;
    T_dh.alpha=-boost::math::constants::pi<double>()/2;
    tr_transform T_tr=dh_to_tr(T_dh);
    EXPECT_LT((homogeneous_transform(T_tr.rotation.toRotationMatrix(),T_tr.translation)-(Eigen::Matrix4d()<<0.866025,0,-0.5,0.866025,0.5,0,0.866025,0.5,0,-1,0,0,0,0,0,1).finished()).norm(),1e-2);

}

int main(int argc, char *argv[])
{
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

max_stars_repo_name: jackiecx/snark

max_issues_repo_name: jackiecx/snark

max_forks_repo_name: jackiecx/snark


text:
//------------------------------------------------------------------------------
// \file Enumeration_tests.cpp
//------------------------------------------------------------------------------
#include "Cpp/ClassAsEnum.h"
#include "Cpp/Numerics/BitCast.h"
#include "Cpp/Utilities/SuperBitSet.h"
#include "Cpp/Utilities/TypeSupport/UnderlyingTypes.h"

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

using Cpp::ClassAsEnum;
using Cpp::ClassAsEnumClass;
using Cpp::Numerics::bit_cast;
using Cpp::Utilities::SuperBitSet;
using Cpp::Utilities::TypeSupport::get_underlying_value;

BOOST_AUTO_TEST_SUITE(Cpp)
BOOST_AUTO_TEST_SUITE(Enumeration_tests)

enum class NameToValue : char
{
	Alpha = 'a',
	Beta = 'b',
	Gamma = 'c'
};

enum class DefaultUnsignedChars : unsigned char
{
	Zero,
	Un,
	Deux,
	Trois,
	Quatre
};

inline bool operator&(
	const DefaultUnsignedChars x,
	const DefaultUnsignedChars y)
{
	return static_cast<bool>(get_underlying_value(x) & get_underlying_value(y));
};

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(StaticCastToEnumerationType)
{
	BOOST_TEST((static_cast<NameToValue>('a') == NameToValue::Alpha));
	BOOST_TEST((static_cast<NameToValue>('b') == NameToValue::Beta));
	BOOST_TEST((static_cast<NameToValue>('c') == NameToValue::Gamma));

	const NameToValue casted_d {static_cast<NameToValue>('d')};

	BOOST_TEST((casted_d != NameToValue::Alpha));
	BOOST_TEST((casted_d != NameToValue::Beta));
	BOOST_TEST((casted_d != NameToValue::Gamma));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(UnsignedCharValuesDefaultToNumbers)
{
	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Zero) == 0));

	BOOST_TEST(
		static_cast<int>(get_underlying_value(DefaultUnsignedChars::Zero)) == 0);

	//const unsigned int x {0};

	//std::cout << "\n0 as char: " << static_cast<char>(x) << "\n";

	char message[] {0, 1, 2, 3};

	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Zero) == message[0]));
	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Un) == message[1]));
	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Deux) == message[2]));
	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Trois) == message[3]));

	unsigned char message2[] {0, 1, 2, 3};

	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Zero) == message2[0]));
	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Un) == message2[1]));
	BOOST_TEST((get_underlying_value(DefaultUnsignedChars::Deux) == message2[2]));
	BOOST_TEST(
		(get_underlying_value(DefaultUnsignedChars::Trois) == message2[3]));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(EnumClassValuesCanBeComparedWithBitwiseOperations)
{
	BOOST_TEST(
		get_underlying_value(DefaultUnsignedChars::Trois) ==
			get_underlying_value(DefaultUnsignedChars::Un) |
				get_underlying_value(DefaultUnsignedChars::Deux));

	SuperBitSet<8> un_bits8 {bit_cast<uint8_t>(DefaultUnsignedChars::Un)};
	BOOST_TEST(un_bits8.to_string() == "00000001");

	SuperBitSet<8> deux_bits8 {bit_cast<uint8_t>(DefaultUnsignedChars::Deux)};
	BOOST_TEST(deux_bits8.to_string() == "00000010");

	SuperBitSet<8> trois_bits8 {bit_cast<uint8_t>(DefaultUnsignedChars::Trois)};
	BOOST_TEST(trois_bits8.to_string() == "00000011");

	const int32_t un_et_trois {
		get_underlying_value(DefaultUnsignedChars::Un) &
			get_underlying_value(DefaultUnsignedChars::Trois)};

	SuperBitSet<32> un_et_trois_bits32 {bit_cast<uint32_t>(un_et_trois)};
	BOOST_TEST(un_et_trois_bits32.to_string() ==
		"00000000000000000000000000000001");

	/* // Narrowing conversion
	const bool est_un_et_trois {
		get_underlying_value(DefaultUnsignedChars::Un) &
			get_underlying_value(DefaultUnsignedChars::Trois)};
	*/

	BOOST_TEST(static_cast<bool>(un_et_trois));

	const int32_t deux_et_trois {
		get_underlying_value(DefaultUnsignedChars::Deux) &
			get_underlying_value(DefaultUnsignedChars::Trois)};

	SuperBitSet<32> deux_et_trois_bits32 {bit_cast<uint32_t>(deux_et_trois)};
	BOOST_TEST(deux_et_trois_bits32.to_string() ==
		"00000000000000000000000000000010");

	BOOST_TEST(static_cast<bool>(deux_et_trois));

	const int32_t zero_et_trois {
		get_underlying_value(DefaultUnsignedChars::Zero) &
			get_underlying_value(DefaultUnsignedChars::Trois)};
	BOOST_TEST(!static_cast<bool>(zero_et_trois));

	const int32_t quatre_et_trois {
		get_underlying_value(DefaultUnsignedChars::Quatre) &
			get_underlying_value(DefaultUnsignedChars::Trois)};
	BOOST_TEST(!static_cast<bool>(quatre_et_trois));
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(EnumClassValuesAndBitwiseAndOperator)
{
	// error: no match for ‘operator&’ (operand types are ‘Cpp::Enumeration_tests::DefaultUnsignedChars’ and ‘Cpp::Enumeration_tests::DefaultUnsignedChars’)

	const auto underlying_un = get_underlying_value(DefaultUnsignedChars::Un);
	BOOST_TEST(sizeof(underlying_un) == 1);

	// cf. https://stackoverflow.com/questions/17489696/bitwise-shift-promotes-unsigned-char-to-int
	// Because of the standard, language promotes anything smaller than int to int
	// in bitwise operation.
	const auto deux_et_trois =
		get_underlying_value(DefaultUnsignedChars::Deux) &
			get_underlying_value(DefaultUnsignedChars::Trois);

	BOOST_TEST(sizeof(deux_et_trois) > sizeof(unsigned char));
	BOOST_TEST(sizeof(deux_et_trois) == sizeof(int));

	BOOST_TEST(!(DefaultUnsignedChars::Zero & DefaultUnsignedChars::Un));
	BOOST_TEST(!(DefaultUnsignedChars::Zero & DefaultUnsignedChars::Deux));
	BOOST_TEST(!(DefaultUnsignedChars::Zero & DefaultUnsignedChars::Trois));
	BOOST_TEST(!(DefaultUnsignedChars::Zero & DefaultUnsignedChars::Quatre));
	BOOST_TEST(!(DefaultUnsignedChars::Un & DefaultUnsignedChars::Deux));
	BOOST_TEST((DefaultUnsignedChars::Un & DefaultUnsignedChars::Trois));
	BOOST_TEST(!(DefaultUnsignedChars::Un & DefaultUnsignedChars::Quatre));
	BOOST_TEST((DefaultUnsignedChars::Deux & DefaultUnsignedChars::Trois));
	BOOST_TEST(!(DefaultUnsignedChars::Deux & DefaultUnsignedChars::Quatre));
	BOOST_TEST(!(DefaultUnsignedChars::Trois & DefaultUnsignedChars::Quatre));
}

BOOST_AUTO_TEST_SUITE_END() // Enumeration_tests

BOOST_AUTO_TEST_SUITE(ClassAsEnum_tests)

enum AltroEnum : unsigned char
{
	Zero,
	Uno,
	Due,
	Tre,
	Quattro
};

enum class DalsiEnumClass : unsigned char
{
	Nula,
	Jeden,
	Dva,
	Tri,
	Ctyri
};

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ClassAsEnumBehavesAsEnum)
{
	const ClassAsEnum f0 {ClassAsEnum::Zero};
	const ClassAsEnum f1 {ClassAsEnum::Un};

	BOOST_TEST(f0.est_zero());
	BOOST_TEST(f1.est_un_o_trois());

	BOOST_TEST(f0 == ClassAsEnum::Zero);
	BOOST_TEST(f1 == ClassAsEnum::Un);

}

#ifdef FORCE_COMPILE_WARNING
// Compilation warning:
// warning: comparison between ‘enum Cpp::ClassAsEnum::Valeur’ and ‘enum Cpp::ClassAsEnum_tests::AltroEnum’
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ClassAsEnumComparesWithOtherEnumValues)
{
	ClassAsEnum::Zero == AltroEnum::Zero;
	ClassAsEnum::Un == AltroEnum::Uno;
}

#endif // FORCE_COMPILE_WARNING

#ifdef FORCE_COMPILE_ERROR
// Compilation error: no match for ‘operator==’
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ClassAsEnumDoesNotCompareWithOtherEnumClassValues)
{
	ClassAsEnum::Zero == DalsiEnumClass::Nula;
	ClassAsEnum::Un == DalsiEnumClass::Jeden;
}
#endif // FORCE_COMPILE_ERROR

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ClassAsEnumClassConstructs)
{
	const ClassAsEnumClass f0 {ClassAsEnumClass::Valeur::Zero};
	const ClassAsEnumClass f1 {ClassAsEnumClass::Valeur::Un};

	BOOST_TEST(f0.est_zero());
	BOOST_TEST(f1.est_un_o_trois());
	BOOST_TEST(!f1.est_deux_o_trois());
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOST_AUTO_TEST_CASE(ClassAsEnumClassComparesWithOtherEnumValues)
{
	const ClassAsEnumClass f0 {ClassAsEnumClass::Valeur::Zero};
	const ClassAsEnumClass f1 {ClassAsEnumClass::Valeur::Un};

	//f0 == AltroEnum::Zero;
}

BOOST_AUTO_TEST_SUITE_END() // ClassAsEnum_tests

BOOST_AUTO_TEST_SUITE_END() // Cpp

max_stars_repo_name: ernestyalumni/HrdwCCppCUDA

max_issues_repo_name: ernestyalumni/HrdwCCppCUDA

max_forks_repo_name: ernestyalumni/HrdwCCppCUDA