text:
/*
Copyright 2018 Rui Miguel Horta Pimentel de Figueiredo

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/*!
    \author Rui Figueiredo : ruipimentelfigueiredo
*/

#include <ctime>
#include <chrono>
#include <boost/filesystem.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include <tf/tf.h>

#include "config.h"
#include "helpers.h"
#include "planar_top_detector.h"

// ROS
#include <std_msgs/Header.h>
#include <cv_bridge/cv_bridge.h>
#include <visualization_msgs/MarkerArray.h>

#include <pcl_conversions/pcl_conversions.h>
#include <pcl_ros/point_cloud.h>
#include "annotations.h"

class GroundTruthDetection
{
	public:
	cv::Rect bbox;
	cv::Scalar color;
	GroundTruthDetection(cv::Rect & bbox_, cv::Scalar & color_) : bbox(bbox_), color(color_)
	{};
};

class Filenames
{
	public:
		std::vector<std::string> file_names;

		Filenames(const std::string & dataset_path_)
		{
			boost::filesystem::path p(dataset_path_);
			boost::filesystem::directory_iterator start(p);
			boost::filesystem::directory_iterator end;
			std::transform(start, end, std::back_inserter(file_names), path_leaf_string());
			std::sort(file_names.begin(), file_names.end());
		}
};

std::map<int, Color> id_colors_map_shape;
std::map<int, cv::Scalar> id_colors_map_bb;
const std::string marker_detections_namespace_ = "detections";

ros::Publisher shape_markers_pub;
ros::Publisher cloud_markers_pub;
ros::Publisher image_pub;
ros::Publisher image_detections_pub;

ros::Publisher point_cloud_pub;
typedef pcl::PointCloud<pcl::PointXYZ> PointCloud;

visualization_msgs::Marker createCylinderMarker(const Eigen::VectorXf &model_params, int model_type, const std::string &frame, Color &color_, int id, const std::string &marker_namespace_)
{
	// Convert direction vector to quaternion
	tf::Vector3 axis_vector(model_params[3], model_params[4], model_params[5]);

	tf::Vector3 up_vector(0.0, 0.0, 1.0);
	tf::Quaternion q;
	if (axis_vector.dot(up_vector) > 0.99)
	{
		q = tf::createIdentityQuaternion();
	}
	else
	{
		tf::Vector3 right_vector = axis_vector.cross(up_vector);
		right_vector.normalized();
		q = tf::Quaternion(right_vector, -1.0 * acos(axis_vector.dot(up_vector)));
	}

	q.normalize();
	geometry_msgs::Quaternion cylinder_orientation;
	tf::quaternionTFToMsg(q, cylinder_orientation);
	float height = model_params[7];

	visualization_msgs::Marker marker;
	marker.header.frame_id = frame;
	marker.header.stamp = ros::Time();
	marker.ns = marker_namespace_;
	marker.id = id;
	marker.type = model_type;
	marker.action = visualization_msgs::Marker::ADD;
	marker.pose.position.x = model_params[0];
	marker.pose.position.y = model_params[1];
	marker.pose.position.z = model_params[2];
	marker.pose.orientation = cylinder_orientation;

	marker.scale.x = 2 * model_params[6];
	marker.scale.y = 2 * model_params[6];
	marker.scale.z = height;

	marker.color.a = color_.a;
	marker.color.r = color_.r;
	marker.color.g = color_.g;
	marker.color.b = color_.b;

	return marker;
}

std::vector<GroundTruthDetection> parseGroundTruth(std::string file, boost::shared_ptr<TiXmlDocument> doc)
{
	std::vector<GroundTruthDetection> ground_truth;

	// Load ground truth file
	doc->LoadFile(file);
	TiXmlElement *pRoot = doc->FirstChildElement("annotation");
	TiXmlElement *objParam;
	if(pRoot)
	{
		objParam = pRoot->FirstChildElement("object");

		while(objParam)
		{
			TiXmlElement* bndbox = objParam->FirstChildElement("bndbox");
			cv::Rect rect;
			if(bndbox)
			{
				int xmin(0),xmax(0),ymin(0),ymax(0);

				TiXmlElement *xminParam = bndbox->FirstChildElement("xmin");
				if(xminParam)
					xmin=atoi(xminParam->GetText());
				TiXmlElement *yminParam = bndbox->FirstChildElement("ymin");
				if(yminParam)
					ymin=atoi(yminParam->GetText());
				TiXmlElement *xmaxParam = bndbox->FirstChildElement("xmax");
				if(xmaxParam)
					xmax=atoi(xmaxParam->GetText());
				TiXmlElement *ymaxParam = bndbox->FirstChildElement("ymax");
				if(ymaxParam)
					ymax=atoi(ymaxParam->GetText());

				rect=cv::Rect(xmin,ymin,(xmax-xmin),(ymax-ymin));
			}
			else
				continue;

			TiXmlElement* typeParam = objParam->FirstChildElement("name");
			std::string type=std::string(typeParam->GetText());

			cv::Scalar color;
			if(type=="cylinder")
				color=cv::Scalar(0,0,255);
			else if(type=="sphere")
				color=cv::Scalar(0,255,0);
			else if(type=="box")
				color=cv::Scalar(255,0,0);

			objParam = objParam->NextSiblingElement("object");

			ground_truth.push_back(GroundTruthDetection(rect,color));
		}
	}
	return ground_truth;
};

visualization_msgs::Marker getCloudMarker(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &cloud)
{
	static bool first_time = true;
	if (first_time)
	{
		srand(time(NULL));
		first_time = false;
	}

	//create the marker
	visualization_msgs::Marker marker;
	marker.action = visualization_msgs::Marker::ADD;
	marker.lifetime = ros::Duration(5);

	marker.type = visualization_msgs::Marker::POINTS;
	marker.scale.x = 0.002;
	marker.scale.y = 0.002;
	marker.scale.z = 0.002;

	marker.color.r = ((double)rand()) / RAND_MAX;
	marker.color.g = ((double)rand()) / RAND_MAX;
	marker.color.b = ((double)rand()) / RAND_MAX;
	marker.color.a = 1.0;

	for (size_t i = 0; i < cloud->points.size(); ++i)
	{
		geometry_msgs::Point p;
		p.x = cloud->points[i].x;
		p.y = cloud->points[i].y;
		p.z = cloud->points[i].z;
		marker.points.push_back(p);
	}

	//the caller must decide the header; we are done here
	return marker;
}

void visualize(const pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr &cloud, DetectionData &detections, cv_bridge::CvImagePtr &cv_ptr)
{
	visualization_msgs::MarkerArray shape_markers_;
	visualization_msgs::MarkerArray cloud_markers_;

	visualization_msgs::Marker clean_shapes_marker_;
	clean_shapes_marker_.action = 3;
	shape_markers_.markers.push_back(clean_shapes_marker_);
	cloud_markers_.markers.push_back(clean_shapes_marker_);

	std::vector<cv::Scalar> colors_cv;
	visualization_msgs::Marker cloud_marker=getCloudMarker(detections.plane_fitting_data.inliers);

	pcl_conversions::fromPCL(cloud->header, cloud_marker.header);
	cloud_marker.header.frame_id="world";

	cloud_marker.pose.orientation.w = 1;
	cloud_marker.ns = "table";
	cloud_markers_.markers.push_back(cloud_marker);

	// Get table contour marker
	visualization_msgs::Marker table_contour_cloud_marker=getCloudMarker(detections.plane_fitting_data.contour);

	table_contour_cloud_marker.header.frame_id="world";
	table_contour_cloud_marker.pose.orientation.w = 1;
	table_contour_cloud_marker.ns = "table_contour";
	cloud_markers_.markers.push_back(table_contour_cloud_marker);

	for (unsigned int ind = 0; ind < detections.clusters_fitting_data.size(); ++ind)
	{
		// Cylinder shape
		if (detections.clusters_fitting_data[ind].type == FittingData::CYLINDER)
		{
			if (detections.clusters_fitting_data[ind].parameters.size() == 0)
				continue;

			// Cluster inliers marker
			visualization_msgs::Marker cluster_marker=getCloudMarker(detections.clusters_fitting_data[ind].inliers);
			cluster_marker.header = cloud_marker.header;
			cluster_marker.pose.orientation.w = 1;
			cluster_marker.ns = "clusters";
			cluster_marker.id=ind;
			cloud_markers_.markers.push_back(cluster_marker);

			// Shape marker
			FittingData fitting_data = detections.clusters_fitting_data[ind];
			Eigen::VectorXf model_params = fitting_data.parameters;

			Color color_;
			cv::Scalar color_cv;
			visualization_msgs::Marker marker;

			// If no classifier and fitting error less than a given threshold -> cylinder
			if(!detections.with_classifier)
			{
				color_cv = id_colors_map_bb.find(2)->second;
				if(detections.clusters_fitting_data[ind].confidence>FittingData::fitting_threshold)
				{
					color_ = id_colors_map_shape.find(0)->second;
				}
				else
				{
					color_ = id_colors_map_shape.find(1)->second;
				}
			}
			else
			{
				color_ = id_colors_map_shape.find(0)->second;
				color_cv = id_colors_map_bb.find(0)->second;
			}

			marker = createCylinderMarker(model_params, visualization_msgs::Marker::CYLINDER, cloud->header.frame_id, color_, ind, marker_detections_namespace_);
			marker.header = cloud_marker.header;
			colors_cv.push_back(color_cv);

			shape_markers_.markers.push_back(marker);
		}
		else
		{
			cv::Scalar color_cv = id_colors_map_bb.find(1)->second;
			colors_cv.push_back(color_cv);
		}
	}

	// Publish data
	image_pub.publish(cv_ptr);
	cv_bridge::CvImagePtr cv_ptr_det(new cv_bridge::CvImage());
	*cv_ptr_det=*cv_ptr;
	detections.draw_bounding_boxes(cv_ptr_det->image, colors_cv);
	image_detections_pub.publish(cv_ptr_det);
	shape_markers_pub.publish(shape_markers_);
	cloud_markers_pub.publish(cloud_markers_);
	point_cloud_pub.publish(cloud);
}

int main (int argc, char** argv)
{
	ros::init(argc, argv, "shape_detection_fitting");
	ros::NodeHandle n;

	// Arguments
	std::string config_file=std::string(argv[1]);

	Config config;
	config.parseConfig(config_file);

	std::vector<std::string> image_files,annotation_files,point_cloud_files;

	std::string dataset_path=config.dataset_path;

	// Test set path
	std::string images_dataset_path=dataset_path+"/images/"+config.object_type+"/";
	std::string point_clouds_dataset_path=dataset_path+"/pointclouds/"+config.object_type+"/";
	std::string annotations_dataset_path=dataset_path+"/annotations/"+config.object_type+"/";

	std::string results_path;
	std::string results_images_clusters_path;
	std::string results_annotations_path;
	std::string results_times_path;
	std::string resuls_score_path;

	// Results path
	if(config.with_classifier)
	{
		results_path=dataset_path+"/results/"+config.object_type+"/with_classifier/";
	}
	else
	{
		results_path=dataset_path+"/results/"+config.object_type+"/no_classifier/";
	}

	results_images_clusters_path=results_path+"images_clusters/";
	results_annotations_path    =results_path+"annotations/";
	results_times_path    =results_path+"times/";
	resuls_score_path     =results_path+"scores/";

	boost::shared_ptr<VisualizeFittingData> visualizer;

	if(config.visualize)
		visualizer=boost::shared_ptr<VisualizeFittingData>(new VisualizeFittingData());

	boost::shared_ptr<TiXmlDocument> doc(new TiXmlDocument());

	createDirectory(results_images_clusters_path);
	createDirectory(results_annotations_path);
	createDirectory(results_times_path);
	createDirectory(resuls_score_path);

	boost::shared_ptr<CylinderClassifier> cylinder_classifier;
	if(config.with_classifier)
		cylinder_classifier=boost::shared_ptr<CylinderClassifier> (new CylinderClassifier(config.classifier_absolute_path_folder,config.model_file,config.weight_file,config.mean_file,config.device,(unsigned int)config.device_id));

	GaussianSphere gaussian_sphere(config.gmm,config.gaussian_sphere_points_num,config.orientation_accumulators_num);

	boost::shared_ptr<SphereFittingHough> sphere_fitting(new SphereFittingHough(gaussian_sphere,config.position_bins,config.radius_bins,config.min_radius, config.max_radius,config.accumulator_peak_threshold));
	boost::shared_ptr<CylinderFittingHough> cylinder_fitting(new CylinderFittingHough(gaussian_sphere,config.angle_bins,config.radius_bins,config.position_bins,config.min_radius, config.max_radius,config.accumulator_peak_threshold,config.hough_fitting_mode));
	boost::shared_ptr<PlaneFittingRansac> plane_fitting(new PlaneFittingRansac(config.distance_threshold,config.cluster_tolerance,config.min_cluster_size,config.max_cluster_size,config.do_refine,config.table_z_filter_min,config.table_z_filter_max,config.z_filter_min, config.z_filter_max,config.plane_detection_voxel_size, config.cluster_voxel_size,config.inlier_threshold,config.angular_threshold));

	FittingData::fitting_threshold=config.fitting_threshold;

	boost::shared_ptr<PlanarTopDetector<CylinderFittingHough, SphereFittingHough, PlaneFittingRansac> > planar_top_detector(new PlanarTopDetector<CylinderFittingHough, SphereFittingHough, PlaneFittingRansac>(plane_fitting,
		cylinder_classifier,
		cylinder_fitting,
		sphere_fitting,
		config.cam_projection,
		config.classification_threshold,
		config.padding,
		config.cluster_voxel_size,
		config.x_filter_min,
		config.x_filter_max,
		config.z_filter_min,
		config.z_filter_max,
		config.with_classifier,
		config.visualize,
		false,
		config.dataset_path,
		config.object_type));

	std::fstream plane_fitting_time;
	std::fstream cluster_extraction_time;
	std::fstream cluster_classification_time;
	std::fstream cluster_fitting_time;
	std::fstream cluster_fitting_score;

	plane_fitting_time.open(results_times_path+"plane_fitting_time.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
	cluster_extraction_time.open(results_times_path+"cluster_extraction_time.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
	cluster_classification_time.open(results_times_path+"cluster_classification_time.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
	cluster_fitting_time.open(results_times_path+"cluster_fitting_time.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);
	cluster_fitting_score.open(resuls_score_path+"cluster_fitting_score.txt", std::fstream::in | std::fstream::out | std::fstream::trunc);

	// Initialize visualization colors
	id_colors_map_shape.insert(std::pair<int, Color>(0, Color(0, 1, 0, 1.0)));
	id_colors_map_shape.insert(std::pair<int, Color>(1, Color(0, 0, 1, 1.0)));
	id_colors_map_shape.insert(std::pair<int, Color>(2, Color(0.4, 0.1, 0.4)));

	id_colors_map_bb.insert(std::pair<int, cv::Scalar>(0, cv::Scalar(0, 255, 0)));
	id_colors_map_bb.insert(std::pair<int, cv::Scalar>(1, cv::Scalar(0, 0, 255)));
	id_colors_map_bb.insert(std::pair<int, cv::Scalar>(2, cv::Scalar(255, 0, 0)));

	// Initialize advertisers
	shape_markers_pub = n.advertise<visualization_msgs::MarkerArray>("shape_detections_vis", 1);
	cloud_markers_pub = n.advertise<visualization_msgs::MarkerArray>("inlier_detections_vis", 1);
	image_pub         = n.advertise<sensor_msgs::Image>("image", 1);
	image_detections_pub         = n.advertise<sensor_msgs::Image>("image_detections", 1);

	point_cloud_pub   = n.advertise<pcl::PointCloud<pcl::PointXYZRGB> >("cloud_in", 1);

	unsigned int total_directories=sub_directory_count(images_dataset_path);
	unsigned int total_iters=0;
	unsigned int current_dir=0;

	// For each subdirectory
	for (boost::filesystem::directory_iterator itr(images_dataset_path); itr!=boost::filesystem::directory_iterator() && ros::ok(); ++itr)
	{
		current_dir++;
		std::string images_directory_path	    = images_dataset_path+itr->path().filename().string()+"/";
		std::string pointclouds_directory_path  = point_clouds_dataset_path+itr->path().filename().string()+"/";
		std::string ground_truth_directory_path = annotations_dataset_path+itr->path().filename().string()+"/";

		// Get point clouds
		PointClouds point_clouds(pointclouds_directory_path);
		std::vector<std::string> point_clouds_file_names=Filenames(pointclouds_directory_path).file_names;
		std::vector<std::string> images_file_names=Filenames(images_directory_path).file_names;
		std::vector<std::string> annotation_files=Filenames(ground_truth_directory_path).file_names;

		// Read filenames from directory
		//readDirectory(images_directory_path,images_file_names);
		//readDirectory(pointclouds_directory_path,point_cloud_files);
		//readDirectory(ground_truth_directory_path,annotation_files);

		std::string results_annotations_path_current=results_annotations_path+itr->path().filename().string()+"/";
		createDirectory(results_annotations_path_current);

		// For each file
		for(unsigned int i=0;i<point_clouds_file_names.size() && ros::ok();++i)
		{
			try
			{
				// Load RGB data in OpenCV format
				cv::Mat image=cv::imread(images_directory_path+images_file_names[i], CV_LOAD_IMAGE_COLOR);    // Read the file
				if(! image.data )                              											// Check for invalid input
				{
					std::cout <<  "Could not open or find the image " << image_files[i] << std::endl ;
					return -1;
				}

				// Load 3D point cloud information in PCL format
				pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_color(new pcl::PointCloud<pcl::PointXYZRGB>());
				pcl::PointCloud<pcl::PointXYZ>::Ptr point_cloud(new pcl::PointCloud<pcl::PointXYZ>());

				point_cloud_color=point_clouds.loadPointCloudRGB(pointclouds_directory_path+point_clouds.file_names[i]);
				//point_cloud=point_clouds.loadPointCloud(pointclouds_directory_path+point_clouds.file_names[i]);
				pcl::copyPointCloud(*point_cloud_color, *point_cloud);

				point_cloud->header.frame_id=std::string("world");

				// Load ground truth file
				std::vector<GroundTruthDetection> bboxes=parseGroundTruth(ground_truth_directory_path+annotation_files[i],doc);
				std::vector<long int> durations;
				point_cloud_color->header.frame_id="world";

				/* VISUALIZE GROUND TRUTH */
				if(config.visualize_ground_truth)
				{
					visualizer->clear();
					for(unsigned int i = 0; i<bboxes.size(); ++i)
					{
						cv::rectangle(image, bboxes[i].bbox, bboxes[i].color, 2, 4, 0 );
					}
				}
				/* END VISUALIZE GROUND TRUTH */

				DetectionData detections;//=planar_top_detector->detect(image,point_cloud_color,visualizer,durations);
				try
				{
					detections=planar_top_detector->detect(image,point_cloud_color,visualizer,durations);
				}
				catch (std::exception& e)
				{
					std::cout << "iteration: " << i << std::endl;
					std::cout << e.what() << std::endl;
					continue;
				}

				/* VISUALIZE */
				cv_bridge::CvImagePtr cv_img(new cv_bridge::CvImage());
				cv_img->image=image;
				cv_img->encoding="bgr8";
				visualize(point_cloud_color, detections, cv_img);
				/* END VISUALIZE */

				/* RECORD RESULTS DATA */
				// TIMMINGS
				plane_fitting_time              << durations[0] << " \n";
				cluster_extraction_time         << durations[1] << " \n";
				cluster_classification_time 	<< durations[2] << " \n";
				cluster_fitting_time 			<< durations[3] << " \n";
				for(unsigned int i=0; i<detections.clusters_fitting_data.size();++i)
					cluster_fitting_score 	<< detections.clusters_fitting_data[i].confidence << " \n";

				// FITTING SCORE (TODO: ADD FITTING SCORE TO THE XML FILE)

				// DETECTION
				std::vector<cv::Rect> bounding_boxes;
        		std::vector<PointCloudT::Ptr> pcl_clusters;
				annotations::storeTestData(results_images_clusters_path,results_annotations_path_current,annotation_files[i],(i+1),detections,config.with_classifier);
				/* END RECORD RESULTS DATA */
				++total_iters;
				double total_time;
				total_time = std::accumulate(durations.begin(), durations.end(), 0);
				std::cout 	<< "with_classifier: " << config.with_classifier << " set: " << current_dir << " of " << total_directories
							<< " iteration: " << (i+1) << " of " << point_clouds.file_names.size()
							<< " total iterations: " << total_iters
							<< " plane fitting time: " << durations[0] << " ms "
							<< " cluster extraction time: " << durations[1] << " ms "
							<< " classification: " << durations[2] << " ms "
							<< " fitting: " << durations[3] << " ms "
							<< " total_time: " << total_time << " ms "

							<< std::endl;
			}
			catch (exception& e)
			{
				std::cout << e.what() << std::endl;
				continue;
			}
			ros::Duration(0.1).sleep(); // sleep for visualization purposes
		}
	}
	plane_fitting_time.close();
	cluster_extraction_time.close();
	cluster_classification_time.close();
	cluster_fitting_time.close();
	return 0;
}


text: #include <boost/mpl/aux_/preprocessed/mwcw/or.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text: #include <boost/spirit/include/classic_tree_to_xml.hpp>


text:
#ifndef MIME_HPP
#define MIME_HPP

#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>

namespace net {
namespace http {
namespace mime {

// Return a reasonable mime type based on the extension of a file.
static inline boost::beast::string_view type(boost::beast::string_view path) {
  using namespace boost;
  using beast::iequals;
  const auto ext = [&path] {
    const auto pos = path.rfind(".");
    return pos == beast::string_view::npos ? beast::string_view{}
                                           : path.substr(pos);
  }();

  if (iequals(ext, ".htm")) {
    return "text/html";
  } else if (iequals(ext, ".html")) {
    return "text/html";
  } else if (iequals(ext, ".php")) {
    return "text/html";
  } else if (iequals(ext, ".css")) {
    return "text/css";
  } else if (iequals(ext, ".txt")) {
    return "text/plain";
  } else if (iequals(ext, ".js")) {
    return "application/javascript";
  } else if (iequals(ext, ".json")) {
    return "application/json";
  } else if (iequals(ext, ".xml")) {
    return "application/xml";
  } else if (iequals(ext, ".swf")) {
    return "application/x-shockwave-flash";
  } else if (iequals(ext, ".flv")) {
    return "video/x-flv";
  } else if (iequals(ext, ".png")) {
    return "image/png";
  } else if (iequals(ext, ".jpe")) {
    return "image/jpeg";
  } else if (iequals(ext, ".jpeg")) {
    return "image/jpeg";
  } else if (iequals(ext, ".jpg")) {
    return "image/jpeg";
  } else if (iequals(ext, ".gif")) {
    return "image/gif";
  } else if (iequals(ext, ".bmp")) {
    return "image/bmp";
  } else if (iequals(ext, ".ico")) {
    return "image/vnd.microsoft.icon";
  } else if (iequals(ext, ".tiff")) {
    return "image/tiff";
  } else if (iequals(ext, ".tif")) {
    return "image/tiff";
  } else if (iequals(ext, ".svg")) {
    return "image/svg+xml";
  } else if (iequals(ext, ".svgz")) {
    return "image/svg+xml";
  } else {
    return "application/text";
  }
}

} // namespace mime
} // namespace http
} // namespace net

#endif

max_stars_repo_name: mnrn/game-memo

max_issues_repo_name: mnrn/game-memo

max_forks_repo_name: mnrn/game-memo


text:
#include <ysu/crypto_lib/random_pool.hpp>
#include <ysu/lib/config.hpp>
#include <ysu/lib/numbers.hpp>
#include <ysu/secure/blockstore.hpp>
#include <ysu/secure/common.hpp>

#include <crypto/cryptopp/words.h>

#include <boost/endian/conversion.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/variant/get.hpp>

#include <limits>
#include <queue>

#include <crypto/ed25519-donna/ed25519.h>

size_t constexpr ysu::send_block::size;
size_t constexpr ysu::receive_block::size;
size_t constexpr ysu::open_block::size;
size_t constexpr ysu::change_block::size;
size_t constexpr ysu::state_block::size;

ysu::ysu_networks ysu::network_constants::active_network = ysu::ysu_networks::ACTIVE_NETWORK;

namespace
{
char const * dev_private_key_data = "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4";
char const * dev_public_key_data = "B0311EA55708D6A53C75CDBF88300259C6D018522FE3D4D0A242E431F9E8B6D0"; // xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo
char const * beta_public_key_data = "A59A439B34662385D48F7FF9CA50030F889BAA9AC320EA5A85AAD777CF82B088"; // ysu_3betagfmasj5iqcayzzssba185wamgobois1xbfadcpqgz9r7e6a1zwztn5o
char const * live_public_key_data = "E89208DD038FBB269987689621D52292AE9C35941A7484756ECCED92A65093BA"; // xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3
char const * test_public_key_data = "45C6FF9D1706D61F0821327752671BDA9F9ED2DA40326B01935AB566FB9E08ED"; // ysu_1jg8zygjg3pp5w644emqcbmjqpnzmubfni3kfe1s8pooeuxsw49fdq1mco9j
char const * dev_genesis_data = R"%%%({
	"type": "open",
	"source": "B0311EA55708D6A53C75CDBF88300259C6D018522FE3D4D0A242E431F9E8B6D0",
	"representative": "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo",
	"account": "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo",
	"work": "7b42a00ee91d5810",
	"signature": "ECDA914373A2F0CA1296475BAEE40500A7F0A7AD72A5A80C81D7FAB7F6C802B2CC7DB50F5DD0FB25B2EF11761FA7344A158DD5A700B21BD47DE5BD0F63153A02"
	})%%%";

char const * beta_genesis_data = R"%%%({
	"type": "open",
	"source": "A59A439B34662385D48F7FF9CA50030F889BAA9AC320EA5A85AAD777CF82B088",
	"representative": "ysu_3betagfmasj5iqcayzzssba185wamgobois1xbfadcpqgz9r7e6a1zwztn5o",
	"account": "ysu_3betagfmasj5iqcayzzssba185wamgobois1xbfadcpqgz9r7e6a1zwztn5o",
	"work": "a870b0e9331cf477",
	"signature": "2F4D72B8E973C979E4D6815CB34C2F426AD997FB8BC6BD94C92541E7F35879594A392AA0B28D0A865EA4C73DB2DE56893E947FD0AD76AB847A2BB5AEDFBF0E00"
	})%%%";

char const * live_genesis_data = R"%%%({
	"type": "open",
	"source": "E89208DD038FBB269987689621D52292AE9C35941A7484756ECCED92A65093BA",
	"representative": "xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3",
	"account": "xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3",
	"work": "62f05417dd3fb691",
	"signature": "9F0C933C8ADE004D808EA1985FA746A7E95BA2A38F867640F53EC8F180BDFE9E2C1268DEAD7C2664F356E37ABA362BC58E46DBA03E523A7B5A19E4B6EB12BB02"
	})%%%";

char const * test_genesis_data = R"%%%({
	"type": "open",
	"source": "45C6FF9D1706D61F0821327752671BDA9F9ED2DA40326B01935AB566FB9E08ED",
	"representative": "ysu_1jg8zygjg3pp5w644emqcbmjqpnzmubfni3kfe1s8pooeuxsw49fdq1mco9j",
	"account": "ysu_1jg8zygjg3pp5w644emqcbmjqpnzmubfni3kfe1s8pooeuxsw49fdq1mco9j",
	"work": "bc1ef279c1a34eb1",
	"signature": "15049467CAEE3EC768639E8E35792399B6078DA763DA4EBA8ECAD33B0EDC4AF2E7403893A5A602EB89B978DABEF1D6606BB00F3C0EE11449232B143B6E07170E"
	})%%%";

std::shared_ptr<ysu::block> parse_block_from_genesis_data (std::string const & genesis_data_a)
{
	boost::property_tree::ptree tree;
	std::stringstream istream (genesis_data_a);
	boost::property_tree::read_json (istream, tree);
	return ysu::deserialize_block_json (tree);
}
}

ysu::network_params::network_params () :
network_params (network_constants::active_network)
{
}

ysu::network_params::network_params (ysu::ysu_networks network_a) :
network (network_a), ledger (network), voting (network), node (network), portmapping (network), bootstrap (network)
{
	unsigned constexpr kdf_full_work = 64 * 1024;
	unsigned constexpr kdf_dev_work = 8;
	kdf_work = network.is_dev_network () ? kdf_dev_work : kdf_full_work;
	header_magic_number = network.is_dev_network () ? std::array<uint8_t, 2>{ { 'R', 'A' } } : network.is_beta_network () ? std::array<uint8_t, 2>{ { 'N', 'B' } } : network.is_live_network () ? std::array<uint8_t, 2>{ { 'R', 'C' } } : std::array<uint8_t, 2>{ { 'R', 'X' } };
}

uint8_t ysu::protocol_constants::protocol_version_min (bool use_epoch_2_min_version_a) const
{
	return use_epoch_2_min_version_a ? protocol_version_min_epoch_2 : protocol_version_min_pre_epoch_2;
}

ysu::ledger_constants::ledger_constants (ysu::network_constants & network_constants) :
ledger_constants (network_constants.network ())
{
}

ysu::ledger_constants::ledger_constants (ysu::ysu_networks network_a) :
zero_key ("0"),
dev_genesis_key (dev_private_key_data),
ysu_dev_account (dev_public_key_data),
ysu_beta_account (beta_public_key_data),
ysu_live_account (live_public_key_data),
ysu_test_account (test_public_key_data),
ysu_dev_genesis (dev_genesis_data),
ysu_beta_genesis (beta_genesis_data),
ysu_live_genesis (live_genesis_data),
ysu_test_genesis (test_genesis_data),
genesis_account (network_a == ysu::ysu_networks::ysu_dev_network ? ysu_dev_account : network_a == ysu::ysu_networks::ysu_beta_network ? ysu_beta_account : network_a == ysu::ysu_networks::ysu_test_network ? ysu_test_account : ysu_live_account),
genesis_block (network_a == ysu::ysu_networks::ysu_dev_network ? ysu_dev_genesis : network_a == ysu::ysu_networks::ysu_beta_network ? ysu_beta_genesis : network_a == ysu::ysu_networks::ysu_test_network ? ysu_test_genesis : ysu_live_genesis),
genesis_hash (parse_block_from_genesis_data (genesis_block)->hash ()),
genesis_amount (std::numeric_limits<ysu::uint128_t>::max ()),
burn_account (0)
{
	ysu::link epoch_link_v1;
	const char * epoch_message_v1 ("epoch v1 block");
	strncpy ((char *)epoch_link_v1.bytes.data (), epoch_message_v1, epoch_link_v1.bytes.size ());
	epochs.add (ysu::epoch::epoch_1, genesis_account, epoch_link_v1);

	ysu::link epoch_link_v2;
	ysu::account ysu_live_epoch_v2_signer;
	auto error (ysu_live_epoch_v2_signer.decode_account ("ysu_3qb6o6i1tkzr6jwr5s7eehfxwg9x6eemitdinbpi7u8bjjwsgqfj4wzser3x"));
	debug_assert (!error);
	auto epoch_v2_signer (network_a == ysu::ysu_networks::ysu_dev_network ? ysu_dev_account : network_a == ysu::ysu_networks::ysu_beta_network ? ysu_beta_account : network_a == ysu::ysu_networks::ysu_test_network ? ysu_test_account : ysu_live_epoch_v2_signer);
	const char * epoch_message_v2 ("epoch v2 block");
	strncpy ((char *)epoch_link_v2.bytes.data (), epoch_message_v2, epoch_link_v2.bytes.size ());
	epochs.add (ysu::epoch::epoch_2, epoch_v2_signer, epoch_link_v2);
}

ysu::random_constants::random_constants ()
{
	ysu::random_pool::generate_block (not_an_account.bytes.data (), not_an_account.bytes.size ());
	ysu::random_pool::generate_block (random_128.bytes.data (), random_128.bytes.size ());
}

ysu::node_constants::node_constants (ysu::network_constants & network_constants)
{
	period = network_constants.is_dev_network () ? std::chrono::seconds (1) : std::chrono::seconds (60);
	half_period = network_constants.is_dev_network () ? std::chrono::milliseconds (500) : std::chrono::milliseconds (30 * 1000);
	idle_timeout = network_constants.is_dev_network () ? period * 15 : period * 2;
	cutoff = period * 5;
	syn_cookie_cutoff = std::chrono::seconds (5);
	backup_interval = std::chrono::minutes (5);
	bootstrap_interval = std::chrono::seconds (15 * 60);
	search_pending_interval = network_constants.is_dev_network () ? std::chrono::seconds (1) : std::chrono::seconds (5 * 60);
	peer_interval = search_pending_interval;
	unchecked_cleaning_interval = std::chrono::minutes (30);
	process_confirmed_interval = network_constants.is_dev_network () ? std::chrono::milliseconds (50) : std::chrono::milliseconds (500);
	max_peers_per_ip = network_constants.is_dev_network () ? 10 : 5;
	max_weight_samples = (network_constants.is_live_network () || network_constants.is_test_network ()) ? 4032 : 288;
	weight_period = 5 * 60; // 5 minutes
}

ysu::voting_constants::voting_constants (ysu::network_constants & network_constants)
{
	max_cache = network_constants.is_dev_network () ? 256 : 128 * 1024;
}

ysu::portmapping_constants::portmapping_constants (ysu::network_constants & network_constants)
{
	lease_duration = std::chrono::seconds (1787); // ~30 minutes
	health_check_period = std::chrono::seconds (53);
}

ysu::bootstrap_constants::bootstrap_constants (ysu::network_constants & network_constants)
{
	lazy_max_pull_blocks = network_constants.is_dev_network () ? 2 : 512;
	lazy_min_pull_blocks = network_constants.is_dev_network () ? 1 : 32;
	frontier_retry_limit = network_constants.is_dev_network () ? 2 : 16;
	lazy_retry_limit = network_constants.is_dev_network () ? 2 : frontier_retry_limit * 10;
	lazy_destinations_retry_limit = network_constants.is_dev_network () ? 1 : frontier_retry_limit / 4;
	gap_cache_bootstrap_start_interval = network_constants.is_dev_network () ? std::chrono::milliseconds (5) : std::chrono::milliseconds (30 * 1000);
}

// Create a new random keypair
ysu::keypair::keypair ()
{
	random_pool::generate_block (prv.data.bytes.data (), prv.data.bytes.size ());
	ed25519_publickey (prv.data.bytes.data (), pub.bytes.data ());
}

// Create a keypair given a private key
ysu::keypair::keypair (ysu::raw_key && prv_a) :
prv (std::move (prv_a))
{
	ed25519_publickey (prv.data.bytes.data (), pub.bytes.data ());
}

// Create a keypair given a hex string of the private key
ysu::keypair::keypair (std::string const & prv_a)
{
	auto error (prv.data.decode_hex (prv_a));
	(void)error;
	debug_assert (!error);
	ed25519_publickey (prv.data.bytes.data (), pub.bytes.data ());
}

// Serialize a block prefixed with an 8-bit typecode
void ysu::serialize_block (ysu::stream & stream_a, ysu::block const & block_a)
{
	write (stream_a, block_a.type ());
	block_a.serialize (stream_a);
}

ysu::account_info::account_info (ysu::block_hash const & head_a, ysu::account const & representative_a, ysu::block_hash const & open_block_a, ysu::amount const & balance_a, uint64_t modified_a, uint64_t block_count_a, ysu::epoch epoch_a) :
head (head_a),
representative (representative_a),
open_block (open_block_a),
balance (balance_a),
modified (modified_a),
block_count (block_count_a),
epoch_m (epoch_a)
{
}

bool ysu::account_info::deserialize (ysu::stream & stream_a)
{
	auto error (false);
	try
	{
		ysu::read (stream_a, head.bytes);
		ysu::read (stream_a, representative.bytes);
		ysu::read (stream_a, open_block.bytes);
		ysu::read (stream_a, balance.bytes);
		ysu::read (stream_a, modified);
		ysu::read (stream_a, block_count);
		ysu::read (stream_a, epoch_m);
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}

	return error;
}

bool ysu::account_info::operator== (ysu::account_info const & other_a) const
{
	return head == other_a.head && representative == other_a.representative && open_block == other_a.open_block && balance == other_a.balance && modified == other_a.modified && block_count == other_a.block_count && epoch () == other_a.epoch ();
}

bool ysu::account_info::operator!= (ysu::account_info const & other_a) const
{
	return !(*this == other_a);
}

size_t ysu::account_info::db_size () const
{
	debug_assert (reinterpret_cast<const uint8_t *> (this) == reinterpret_cast<const uint8_t *> (&head));
	debug_assert (reinterpret_cast<const uint8_t *> (&head) + sizeof (head) == reinterpret_cast<const uint8_t *> (&representative));
	debug_assert (reinterpret_cast<const uint8_t *> (&representative) + sizeof (representative) == reinterpret_cast<const uint8_t *> (&open_block));
	debug_assert (reinterpret_cast<const uint8_t *> (&open_block) + sizeof (open_block) == reinterpret_cast<const uint8_t *> (&balance));
	debug_assert (reinterpret_cast<const uint8_t *> (&balance) + sizeof (balance) == reinterpret_cast<const uint8_t *> (&modified));
	debug_assert (reinterpret_cast<const uint8_t *> (&modified) + sizeof (modified) == reinterpret_cast<const uint8_t *> (&block_count));
	debug_assert (reinterpret_cast<const uint8_t *> (&block_count) + sizeof (block_count) == reinterpret_cast<const uint8_t *> (&epoch_m));
	return sizeof (head) + sizeof (representative) + sizeof (open_block) + sizeof (balance) + sizeof (modified) + sizeof (block_count) + sizeof (epoch_m);
}

ysu::epoch ysu::account_info::epoch () const
{
	return epoch_m;
}

ysu::pending_info::pending_info (ysu::account const & source_a, ysu::amount const & amount_a, ysu::epoch epoch_a) :
source (source_a),
amount (amount_a),
epoch (epoch_a)
{
}

bool ysu::pending_info::deserialize (ysu::stream & stream_a)
{
	auto error (false);
	try
	{
		ysu::read (stream_a, source.bytes);
		ysu::read (stream_a, amount.bytes);
		ysu::read (stream_a, epoch);
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}

	return error;
}

size_t ysu::pending_info::db_size () const
{
	return sizeof (source) + sizeof (amount) + sizeof (epoch);
}

bool ysu::pending_info::operator== (ysu::pending_info const & other_a) const
{
	return source == other_a.source && amount == other_a.amount && epoch == other_a.epoch;
}

ysu::pending_key::pending_key (ysu::account const & account_a, ysu::block_hash const & hash_a) :
account (account_a),
hash (hash_a)
{
}

bool ysu::pending_key::deserialize (ysu::stream & stream_a)
{
	auto error (false);
	try
	{
		ysu::read (stream_a, account.bytes);
		ysu::read (stream_a, hash.bytes);
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}

	return error;
}

bool ysu::pending_key::operator== (ysu::pending_key const & other_a) const
{
	return account == other_a.account && hash == other_a.hash;
}

ysu::account const & ysu::pending_key::key () const
{
	return account;
}

ysu::unchecked_info::unchecked_info (std::shared_ptr<ysu::block> block_a, ysu::account const & account_a, uint64_t modified_a, ysu::signature_verification verified_a, bool confirmed_a) :
block (block_a),
account (account_a),
modified (modified_a),
verified (verified_a),
confirmed (confirmed_a)
{
}

void ysu::unchecked_info::serialize (ysu::stream & stream_a) const
{
	debug_assert (block != nullptr);
	ysu::serialize_block (stream_a, *block);
	ysu::write (stream_a, account.bytes);
	ysu::write (stream_a, modified);
	ysu::write (stream_a, verified);
}

bool ysu::unchecked_info::deserialize (ysu::stream & stream_a)
{
	block = ysu::deserialize_block (stream_a);
	bool error (block == nullptr);
	if (!error)
	{
		try
		{
			ysu::read (stream_a, account.bytes);
			ysu::read (stream_a, modified);
			ysu::read (stream_a, verified);
		}
		catch (std::runtime_error const &)
		{
			error = true;
		}
	}
	return error;
}

ysu::endpoint_key::endpoint_key (const std::array<uint8_t, 16> & address_a, uint16_t port_a) :
address (address_a), network_port (boost::endian::native_to_big (port_a))
{
}

const std::array<uint8_t, 16> & ysu::endpoint_key::address_bytes () const
{
	return address;
}

uint16_t ysu::endpoint_key::port () const
{
	return boost::endian::big_to_native (network_port);
}

ysu::confirmation_height_info::confirmation_height_info (uint64_t confirmation_height_a, ysu::block_hash const & confirmed_frontier_a) :
height (confirmation_height_a),
frontier (confirmed_frontier_a)
{
}

void ysu::confirmation_height_info::serialize (ysu::stream & stream_a) const
{
	ysu::write (stream_a, height);
	ysu::write (stream_a, frontier);
}

bool ysu::confirmation_height_info::deserialize (ysu::stream & stream_a)
{
	auto error (false);
	try
	{
		ysu::read (stream_a, height);
		ysu::read (stream_a, frontier);
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}
	return error;
}

ysu::block_info::block_info (ysu::account const & account_a, ysu::amount const & balance_a) :
account (account_a),
balance (balance_a)
{
}

bool ysu::vote::operator== (ysu::vote const & other_a) const
{
	auto blocks_equal (true);
	if (blocks.size () != other_a.blocks.size ())
	{
		blocks_equal = false;
	}
	else
	{
		for (auto i (0); blocks_equal && i < blocks.size (); ++i)
		{
			auto block (blocks[i]);
			auto other_block (other_a.blocks[i]);
			if (block.which () != other_block.which ())
			{
				blocks_equal = false;
			}
			else if (block.which ())
			{
				if (boost::get<ysu::block_hash> (block) != boost::get<ysu::block_hash> (other_block))
				{
					blocks_equal = false;
				}
			}
			else
			{
				if (!(*boost::get<std::shared_ptr<ysu::block>> (block) == *boost::get<std::shared_ptr<ysu::block>> (other_block)))
				{
					blocks_equal = false;
				}
			}
		}
	}
	return sequence == other_a.sequence && blocks_equal && account == other_a.account && signature == other_a.signature;
}

bool ysu::vote::operator!= (ysu::vote const & other_a) const
{
	return !(*this == other_a);
}

void ysu::vote::serialize_json (boost::property_tree::ptree & tree) const
{
	tree.put ("account", account.to_account ());
	tree.put ("signature", signature.number ());
	tree.put ("sequence", std::to_string (sequence));
	boost::property_tree::ptree blocks_tree;
	for (auto block : blocks)
	{
		boost::property_tree::ptree entry;
		if (block.which ())
		{
			entry.put ("", boost::get<ysu::block_hash> (block).to_string ());
		}
		else
		{
			entry.put ("", boost::get<std::shared_ptr<ysu::block>> (block)->hash ().to_string ());
		}
		blocks_tree.push_back (std::make_pair ("", entry));
	}
	tree.add_child ("blocks", blocks_tree);
}

std::string ysu::vote::to_json () const
{
	std::stringstream stream;
	boost::property_tree::ptree tree;
	serialize_json (tree);
	boost::property_tree::write_json (stream, tree);
	return stream.str ();
}

ysu::vote::vote (ysu::vote const & other_a) :
sequence (other_a.sequence),
blocks (other_a.blocks),
account (other_a.account),
signature (other_a.signature)
{
}

ysu::vote::vote (bool & error_a, ysu::stream & stream_a, ysu::block_uniquer * uniquer_a)
{
	error_a = deserialize (stream_a, uniquer_a);
}

ysu::vote::vote (bool & error_a, ysu::stream & stream_a, ysu::block_type type_a, ysu::block_uniquer * uniquer_a)
{
	try
	{
		ysu::read (stream_a, account.bytes);
		ysu::read (stream_a, signature.bytes);
		ysu::read (stream_a, sequence);

		while (stream_a.in_avail () > 0)
		{
			if (type_a == ysu::block_type::not_a_block)
			{
				ysu::block_hash block_hash;
				ysu::read (stream_a, block_hash);
				blocks.push_back (block_hash);
			}
			else
			{
				std::shared_ptr<ysu::block> block (ysu::deserialize_block (stream_a, type_a, uniquer_a));
				if (block == nullptr)
				{
					throw std::runtime_error ("Block is null");
				}
				blocks.push_back (block);
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error_a = true;
	}

	if (blocks.empty ())
	{
		error_a = true;
	}
}

ysu::vote::vote (ysu::account const & account_a, ysu::raw_key const & prv_a, uint64_t sequence_a, std::shared_ptr<ysu::block> block_a) :
sequence (sequence_a),
blocks (1, block_a),
account (account_a),
signature (ysu::sign_message (prv_a, account_a, hash ()))
{
}

ysu::vote::vote (ysu::account const & account_a, ysu::raw_key const & prv_a, uint64_t sequence_a, std::vector<ysu::block_hash> const & blocks_a) :
sequence (sequence_a),
account (account_a)
{
	debug_assert (!blocks_a.empty ());
	debug_assert (blocks_a.size () <= 12);
	blocks.reserve (blocks_a.size ());
	std::copy (blocks_a.cbegin (), blocks_a.cend (), std::back_inserter (blocks));
	signature = ysu::sign_message (prv_a, account_a, hash ());
}

std::string ysu::vote::hashes_string () const
{
	std::string result;
	for (auto hash : *this)
	{
		result += hash.to_string ();
		result += ", ";
	}
	return result;
}

const std::string ysu::vote::hash_prefix = "vote ";

ysu::block_hash ysu::vote::hash () const
{
	ysu::block_hash result;
	blake2b_state hash;
	blake2b_init (&hash, sizeof (result.bytes));
	if (blocks.size () > 1 || (!blocks.empty () && blocks.front ().which ()))
	{
		blake2b_update (&hash, hash_prefix.data (), hash_prefix.size ());
	}
	for (auto block_hash : *this)
	{
		blake2b_update (&hash, block_hash.bytes.data (), sizeof (block_hash.bytes));
	}
	union
	{
		uint64_t qword;
		std::array<uint8_t, 8> bytes;
	};
	qword = sequence;
	blake2b_update (&hash, bytes.data (), sizeof (bytes));
	blake2b_final (&hash, result.bytes.data (), sizeof (result.bytes));
	return result;
}

ysu::block_hash ysu::vote::full_hash () const
{
	ysu::block_hash result;
	blake2b_state state;
	blake2b_init (&state, sizeof (result.bytes));
	blake2b_update (&state, hash ().bytes.data (), sizeof (hash ().bytes));
	blake2b_update (&state, account.bytes.data (), sizeof (account.bytes.data ()));
	blake2b_update (&state, signature.bytes.data (), sizeof (signature.bytes.data ()));
	blake2b_final (&state, result.bytes.data (), sizeof (result.bytes));
	return result;
}

void ysu::vote::serialize (ysu::stream & stream_a, ysu::block_type type) const
{
	write (stream_a, account);
	write (stream_a, signature);
	write (stream_a, sequence);
	for (auto const & block : blocks)
	{
		if (block.which ())
		{
			debug_assert (type == ysu::block_type::not_a_block);
			write (stream_a, boost::get<ysu::block_hash> (block));
		}
		else
		{
			if (type == ysu::block_type::not_a_block)
			{
				write (stream_a, boost::get<std::shared_ptr<ysu::block>> (block)->hash ());
			}
			else
			{
				boost::get<std::shared_ptr<ysu::block>> (block)->serialize (stream_a);
			}
		}
	}
}

void ysu::vote::serialize (ysu::stream & stream_a) const
{
	write (stream_a, account);
	write (stream_a, signature);
	write (stream_a, sequence);
	for (auto const & block : blocks)
	{
		if (block.which ())
		{
			write (stream_a, ysu::block_type::not_a_block);
			write (stream_a, boost::get<ysu::block_hash> (block));
		}
		else
		{
			ysu::serialize_block (stream_a, *boost::get<std::shared_ptr<ysu::block>> (block));
		}
	}
}

bool ysu::vote::deserialize (ysu::stream & stream_a, ysu::block_uniquer * uniquer_a)
{
	auto error (false);
	try
	{
		ysu::read (stream_a, account);
		ysu::read (stream_a, signature);
		ysu::read (stream_a, sequence);

		ysu::block_type type;

		while (true)
		{
			if (ysu::try_read (stream_a, type))
			{
				// Reached the end of the stream
				break;
			}

			if (type == ysu::block_type::not_a_block)
			{
				ysu::block_hash block_hash;
				ysu::read (stream_a, block_hash);
				blocks.push_back (block_hash);
			}
			else
			{
				std::shared_ptr<ysu::block> block (ysu::deserialize_block (stream_a, type, uniquer_a));
				if (block == nullptr)
				{
					throw std::runtime_error ("Block is empty");
				}

				blocks.push_back (block);
			}
		}
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}

	if (blocks.empty ())
	{
		error = true;
	}

	return error;
}

bool ysu::vote::validate () const
{
	return ysu::validate_message (account, hash (), signature);
}

ysu::block_hash ysu::iterate_vote_blocks_as_hash::operator() (boost::variant<std::shared_ptr<ysu::block>, ysu::block_hash> const & item) const
{
	ysu::block_hash result;
	if (item.which ())
	{
		result = boost::get<ysu::block_hash> (item);
	}
	else
	{
		result = boost::get<std::shared_ptr<ysu::block>> (item)->hash ();
	}
	return result;
}

boost::transform_iterator<ysu::iterate_vote_blocks_as_hash, ysu::vote_blocks_vec_iter> ysu::vote::begin () const
{
	return boost::transform_iterator<ysu::iterate_vote_blocks_as_hash, ysu::vote_blocks_vec_iter> (blocks.begin (), ysu::iterate_vote_blocks_as_hash ());
}

boost::transform_iterator<ysu::iterate_vote_blocks_as_hash, ysu::vote_blocks_vec_iter> ysu::vote::end () const
{
	return boost::transform_iterator<ysu::iterate_vote_blocks_as_hash, ysu::vote_blocks_vec_iter> (blocks.end (), ysu::iterate_vote_blocks_as_hash ());
}

ysu::vote_uniquer::vote_uniquer (ysu::block_uniquer & uniquer_a) :
uniquer (uniquer_a)
{
}

std::shared_ptr<ysu::vote> ysu::vote_uniquer::unique (std::shared_ptr<ysu::vote> vote_a)
{
	auto result (vote_a);
	if (result != nullptr && !result->blocks.empty ())
	{
		if (!result->blocks.front ().which ())
		{
			result->blocks.front () = uniquer.unique (boost::get<std::shared_ptr<ysu::block>> (result->blocks.front ()));
		}
		ysu::block_hash key (vote_a->full_hash ());
		ysu::lock_guard<std::mutex> lock (mutex);
		auto & existing (votes[key]);
		if (auto block_l = existing.lock ())
		{
			result = block_l;
		}
		else
		{
			existing = vote_a;
		}

		release_assert (std::numeric_limits<CryptoPP::word32>::max () > votes.size ());
		for (auto i (0); i < cleanup_count && !votes.empty (); ++i)
		{
			auto random_offset = ysu::random_pool::generate_word32 (0, static_cast<CryptoPP::word32> (votes.size () - 1));

			auto existing (std::next (votes.begin (), random_offset));
			if (existing == votes.end ())
			{
				existing = votes.begin ();
			}
			if (existing != votes.end ())
			{
				if (auto block_l = existing->second.lock ())
				{
					// Still live
				}
				else
				{
					votes.erase (existing);
				}
			}
		}
	}
	return result;
}

size_t ysu::vote_uniquer::size ()
{
	ysu::lock_guard<std::mutex> lock (mutex);
	return votes.size ();
}

std::unique_ptr<ysu::container_info_component> ysu::collect_container_info (vote_uniquer & vote_uniquer, const std::string & name)
{
	auto count = vote_uniquer.size ();
	auto sizeof_element = sizeof (vote_uniquer::value_type);
	auto composite = std::make_unique<container_info_composite> (name);
	composite->add_component (std::make_unique<container_info_leaf> (container_info{ "votes", count, sizeof_element }));
	return composite;
}

ysu::genesis::genesis ()
{
	static ysu::network_params network_params;
	open = parse_block_from_genesis_data (network_params.ledger.genesis_block);
	debug_assert (open != nullptr);
}

ysu::block_hash ysu::genesis::hash () const
{
	return open->hash ();
}

ysu::wallet_id ysu::random_wallet_id ()
{
	ysu::wallet_id wallet_id;
	ysu::uint256_union dummy_secret;
	random_pool::generate_block (dummy_secret.bytes.data (), dummy_secret.bytes.size ());
	ed25519_publickey (dummy_secret.bytes.data (), wallet_id.bytes.data ());
	return wallet_id;
}

ysu::unchecked_key::unchecked_key (ysu::block_hash const & previous_a, ysu::block_hash const & hash_a) :
previous (previous_a),
hash (hash_a)
{
}

bool ysu::unchecked_key::deserialize (ysu::stream & stream_a)
{
	auto error (false);
	try
	{
		ysu::read (stream_a, previous.bytes);
		ysu::read (stream_a, hash.bytes);
	}
	catch (std::runtime_error const &)
	{
		error = true;
	}

	return error;
}

bool ysu::unchecked_key::operator== (ysu::unchecked_key const & other_a) const
{
	return previous == other_a.previous && hash == other_a.hash;
}

ysu::block_hash const & ysu::unchecked_key::key () const
{
	return previous;
}

void ysu::generate_cache::enable_all ()
{
	reps = true;
	cemented_count = true;
	unchecked_count = true;
	account_count = true;
	epoch_2 = true;
}

ext: cpp


text:
// This file is part of snark, a generic and flexible library for robotics research
// Copyright (c) 2011 The University of Sydney
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the University of Sydney nor the
//    names of its contributors may be used to endorse or promote products
//    derived from this software without specific prior written permission.
//
// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
// GRANTED BY THIS LICENSE.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
// HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <algorithm>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <boost/thread.hpp>
#include <boost/assign.hpp>
#include <boost/bimap.hpp>
#include <boost/bind.hpp>
#include <comma/base/exception.h>
#include <comma/csv/stream.h>
#include "flycapture.h"
#include "helpers.h"

namespace snark{ namespace cameras{ namespace flycapture{

    void assert_ok(const FlyCapture2::Error error, const std::string& error_string)
    {
        if (error != FlyCapture2::PGRERROR_OK)
            { COMMA_THROW(comma::exception, error_string + " (" + std::string(error.GetDescription()) +")"); }
    }

    const std::string get_interface_string( FlyCapture2::InterfaceType interface )
    {
        switch (interface)
        {
            case FlyCapture2::INTERFACE_IEEE1394:
            return "IEEE1394";
            case FlyCapture2::INTERFACE_USB2:
            return "USB2";
            case FlyCapture2::INTERFACE_USB3:
            return "USB3";
            case FlyCapture2::INTERFACE_GIGE:
            return "GigE";
            default:
            return "UNKNOWN";
        }
    }

    unsigned int bits_per_pixel( const FlyCapture2::PixelFormat pixel_format )
    {
        switch( pixel_format )
        {
            case FlyCapture2::PIXEL_FORMAT_MONO8:
            case FlyCapture2::PIXEL_FORMAT_RAW8:
            return 8;
            break;
            case FlyCapture2::PIXEL_FORMAT_RAW16:
            case FlyCapture2::PIXEL_FORMAT_MONO16:
            return 16;
            case FlyCapture2::PIXEL_FORMAT_RGB:
            case FlyCapture2::PIXEL_FORMAT_BGR:
            return 24;
            case FlyCapture2::PIXEL_FORMAT_RGBU:
            case FlyCapture2::PIXEL_FORMAT_BGRU:
            return 32;
            case FlyCapture2::PIXEL_FORMAT_RGB16:
            return 48;
            case FlyCapture2::PIXEL_FORMAT_411YUV8:
            case FlyCapture2::PIXEL_FORMAT_422YUV8:
            case FlyCapture2::PIXEL_FORMAT_444YUV8:
            COMMA_THROW( comma::exception, "unsupported format " << pixel_format );
            default:
            COMMA_THROW( comma::exception, "unknown format " << pixel_format );
            return 0;
        }
    }

    cv::Mat image_as_cvmat( const FlyCapture2::Image& frame )
    {
        int type;
        switch( bits_per_pixel(frame.GetPixelFormat() ) )
        {
            case 8:
            type = CV_8UC1;
            break;
            case 16:
            type = CV_16UC1;
            break;
            case 24:
            type = CV_8UC3;
            break;
            case 32:
            type = CV_8UC4;
            break;
            case 48:
            type = CV_16UC3;
            break;
            default:
            COMMA_THROW( comma::exception, "unknown format " << frame.GetPixelFormat()  );
        };

        return cv::Mat( frame.GetRows(), frame.GetCols(), type, frame.GetData() );
    }

    int get_cv_type( const FlyCapture2::Image& frame )
    {
        switch( bits_per_pixel(frame.GetPixelFormat() ) )
        {
            case 8: return CV_8UC1;
            case 16: return CV_16UC1;
            case 24: return CV_8UC3;
            case 32:return CV_8UC4;
            case 48: return CV_16UC3;
            default:
            COMMA_THROW( comma::exception, "unknown format " << frame.GetPixelFormat()  );
        };
    }
} } } // namespace snark{ namespace cameras{ namespace flycapture

max_stars_repo_name: mission-systems-pty-ltd/snark

max_issues_repo_name: NEU-LC/snark

max_forks_repo_name: NEU-LC/snark


text:
// This file is part of LatNet Builder.
//
// Copyright (C) 2012-2021  The LatNet Builder author's, supervised by Pierre L'Ecuyer, Universite de Montreal.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "latbuilder/Parser/EmbeddingType.h"
#include "latbuilder/Parser/Lattice.h"
#include "latbuilder/Parser/CommandLine.h"
#include "latbuilder/TextStream.h"
#include "latbuilder/Types.h"

#include "netbuilder/DigitalNet.h"
#include "netbuilder/Types.h"

#include "netbuilder/Parser/OutputStyleParser.h"

#include <fstream>
#include <chrono>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/join.hpp>

namespace LatBuilder{
using TextStream::operator<<;

static unsigned int merit_digits_displayed = 0;

template <LatticeType LR, EmbeddingType ET>
void onLatticeSelected(const Task::Search<LR, ET>& s)
   {
     Dimension currentDim = s.bestLattice().dimension();
     Dimension totalDim = s.dimension();
      unsigned int old_precision = (unsigned int) std::cout.precision();
      if (merit_digits_displayed){
        std::cout.precision(merit_digits_displayed);
      }
      std::string lattice;
      if (s.minObserver().totalCount() == 1){
        lattice = " lattice";
      }
      else{
        lattice = " lattices";
      }

       std::cout << "End coordinate: " << currentDim << "/" << totalDim << " - "
       << s.minObserver().totalCount() << lattice  << " explored (" << s.minObserver().acceptedCount() << " accepted)"
       << " - partial merit value: " << s.bestMeritValue() << std::endl;

      if (merit_digits_displayed){
        std::cout.precision(old_precision);
      }
      if (currentDim < totalDim){
        std::cout << "Begin coordinate " << currentDim+1 << "/" << totalDim << std::endl;
      }
   }

boost::program_options::options_description
makeOptionsDescription()
{
   namespace po = boost::program_options;
   po::options_description desc("allowed options");

   desc.add_options ()
   ("help,h", "produce help message")
   ("version", "show version")
   ("set-type,t", po::value<std::string>(),
    "(required) point set type; possible values:\n"
    "  lattice\n"
    "  net\n")
   ("construction,c", po::value<std::string>(),
   "lattice construction; possible values:\n"
   "  ordinary\n"
   "  polynomial\n")
   ("dimension,d", po::value<std::string>(),
    "(required) point set dimension\n")
   ("size-parameter,s", po::value<std::string>(),
    "(required) modulus of the lattice; possible values:\n"
   "  <modulus>\n"
   "  <base>^<max-level>\n"
   "  input format :\n"
   "  ordinary lattice rules: integer (decimal representation)\n"
   "  polynomial lattice rules: polynomial (list of coefficients: 1011 stands for 1 + X^2 + X^3), or\n"
   "                            2^<max_level> (default irreducible modulus, not available for multilevel)\n"
   )
   ("exploration-method,e", po::value<std::string>(),
    "(required) exploration method; possible values:\n"
    "  evaluation:<a1>,...,<as>\n"
    "  exhaustive\n"
    "  random:<r>\n"
    "  Korobov\n"
    "  random-Korobov:<r>\n"
    "  full-CBC\n"
    "  random-CBC:<r>\n"
    "  fast-CBC\n"
    "  extend:<num-points>:<a1>,...,<as>\n"
    "where <r> is the number of samples, "
    "and <a1>,...,<as> are the components of the generating vector\n")
   ("figure-of-merit,f", po::value<std::string>(),
    "(required) type of figure of merit; format: [CU:]<merit>\n"
    "  where the optional \"CU:\" prefix switches on the coordinate-uniform evaluation algorithm,\n"
    "  and where <merit> is one of:\n"
    "    spectral  (only for ordinary lattice rules, no CU)\n"
    "    P<alpha>  (for both constructions, CU for l_2 norm)\n"
    "    R<alpha>  (only for ordinary lattice rules, CU for l_2 norm)\n"
    "    R         (for both constructions, CU for l_2 norm)\n"
    "    IA<alpha> (for interlaced polynomial lattice rules, CU for l_1 norm)\n"
    "    IB (for interlaced polynomial lattice rules, CU for l_1 norm)\n")
    ("interlacing-factor,i", po::value<std::string>()->default_value("1"),
    "(default: 1) interlacing factor (only for polynomial lattice rules). If larger than one, the constructed"
    "point set is an interlaced polynomial lattice rule. In this case, the figure of merit must be"
    "specific to interlaced polynomial lattice rules.\n")
   ("norm-type,q", po::value<std::string>(),
    "norm type used to combine the value of the projection-dependent figure of merit for all projections; possible values:"
    "    <q>: a real number corresponding the l_<q> norm\n"
    "    inf: corresponding to the `max' norm\n")
   ("weights,w", po::value<std::vector<std::string>>()->multitoken(),
    "(required) whitespace-separated list of weights specifications (the actual weights are the sum of these); possible values:\n"
    "  product:<default>:<coord1-weight>[,...]\n"
    "  order-dependent:<default>:<order-1-weight>,...,<order-s-weight>\n"
    "  POD:<default>:<order-1-weight>,...,<order-s-weight>:<default>:<coord1-weight>[,...]\n"
    "  projection-dependent:<proj-1>:<weight-1>[:<proj-2>:<weight-2>[:...]]\n"
    "    where <proj-n> is a comma-separated list of coordinates\n"
    "  file:\"<file>\"\n"
    "    line format in <file>:\n"
    "      <i1>,<i2>,...: <weight>\n"
    "      order <x>: <weight>\n"
    "      default: <weight>\n"
    "    if <file> is `-' data is read from standard input\n")
   ("weights-power,p", po::value<Real>(),
    "(default: same value as for the --norm-type argument) real number specifying that the weights passed as input will be assumed to be already elevated at that power (a value of `inf' is mapped to 1)\n")
   ("multilevel,M", po::value<std::string>()->default_value("false"),
    "multilevel point set; possible values:\n"
   "  false (default)\n"
   "  true\n")
   ("combiner,C", po::value<std::string>(),
    "(required for multilevel) combiner for multilevel merit values; possible values:\n"
    "  sum\n"
    "  max\n"
    "  level:{<level>|max}\n")
   ("filters,F", po::value<std::vector<std::string>>()->multitoken(),
    "whitespace-separated list of filters for merit values; possible values:\n"
    "  norm[:<levels>] for a default normalization (if available)"
    "  norm:{P<alpha>-SL10|P<alpha>-DPW08|P<alpha>|IA<alpha>|IB}[:<levels>]\n"
    "  low-pass:<threshold>\n"
    "where in the case of multilevel lattices, the optional parameter <levels> specifies the selected levels; possible values:\n"
    "  select[:<min-level>[:<max-level>]] (default)\n")
   ("repeat,r", po::value<unsigned int>()->default_value(1),
    "(optional) number of times the exploration must be executed\n"
   "(can be useful to obtain different results from random exploration)\n")
   ("verbose,v", po::value<int>()->default_value(0),
   "specify the verbosity of the program;\n"
   "ranges between 0 (default) and 3\n")
    ("output-folder,o", po::value<std::string>(),
    "(optional) path to the folder for the outputs of LatNeBuilder. The contents of the folder may be overwritten. If the folder does not exist, it is created. If no path is provided, no output folder is created.")
    ("output-style,O", po::value<std::string>()->default_value(""),
    "(optional) TBD")
   ("merit-digits-displayed", po::value<unsigned int>()->default_value(0),
    "(optional) number of significant figures to use when displaying merit values\n");

   return desc;
}

boost::program_options::variables_map
parse(int argc, const char* argv[])
{
   namespace po = boost::program_options;

   auto desc = makeOptionsDescription();

   po::variables_map opt;
   po::store(po::parse_command_line(argc, argv, desc), opt);
   po::notify(opt);

   if (opt.count("help")) {
      std::cout << desc << std::endl;
      std::exit (0);
   }

   for (const auto x : {"construction", "size-parameter", "exploration-method", "dimension", "figure-of-merit", "norm-type"}) {
      if (opt.count(x) != 1)
         throw std::runtime_error("--" + std::string(x) + " must be specified exactly once (try --help)");
   }

  if (opt.count("combiner") < 1 && opt["multilevel"].as<std::string>() == "true"){
    throw std::runtime_error("--combiner must be specified for multilevel set type (try --help)");
  }

   if (opt.count("weights") < 1)
      throw std::runtime_error("--weights must be specified (try --help)");

   return opt;
}

template <EmbeddingType ET>
std::string helper(const SizeParam<LatticeType::ORDINARY, ET>& param);

template<>
std::string helper(const SizeParam<LatticeType::ORDINARY, EmbeddingType::MULTILEVEL>& param)
{
  return std::to_string(param.base()) + "  // Base\n" + std::to_string(param.maxLevel()) + "  // Maximum level\n";
}

template<>
std::string helper(const SizeParam<LatticeType::ORDINARY, EmbeddingType::UNILEVEL>& param)
{
  return "0  // Base\n0  // Maximum level\n";
}

template <EmbeddingType ET>
std::string helper2(const SizeParam<LatticeType::ORDINARY, ET>& param);

template<>
std::string helper2(const SizeParam<LatticeType::ORDINARY, EmbeddingType::MULTILEVEL>& param)
{
  return ", embedded from " + std::to_string(param.base()) + " to " + std::to_string(param.maxLevel()) + "\n";
}

template<>
std::string helper2(const SizeParam<LatticeType::ORDINARY, EmbeddingType::UNILEVEL>& param)
{
  return "\n";
}

template <EmbeddingType ET>
void executeOrdinary(const Parser::CommandLine<LatticeType::ORDINARY, ET>& cmd, int verbose, unsigned int repeat, std::string outputFolder)
{
   const LatticeType LR = LatticeType::ORDINARY ;
   using namespace std::chrono;

   auto search = cmd.parse();

   const std::string separator = "====================\n";

   std::cout << separator << "    Input" << std::endl << separator << *search << std::endl;
    if (outputFolder != ""){
      std::ofstream outFile;
      std::string fileName = outputFolder + "/input.txt";
      outFile.open(fileName);
      outFile << "Input Command Line: " << cmd.originalCommandLine << std::endl << std::endl;
      outFile << *search;
      outFile.close();
    }

   if (verbose > 0) {
      search->onLatticeSelected().connect(onLatticeSelected<LR,ET>);
      search->setObserverVerbosity(verbose-1);
      search->setVerbose(verbose-2);
   }

   for (unsigned int i = 0; i < repeat; i++) {
        if (repeat > 1){
          std::cout << separator << "      Run " << i+1 << std::endl << separator;
        }
        else{
          std::cout << separator << "Running the task..." << std::endl << separator;
        }

      auto t0 = high_resolution_clock::now();
      search->execute();
      auto t1 = high_resolution_clock::now();

      unsigned int old_precision = (unsigned int) std::cout.precision();
      if (merit_digits_displayed)
   std::cout.precision(merit_digits_displayed);
     const auto lat = search->bestLattice();

   auto dt = duration_cast<duration<double>>(t1 - t0);
         std::cout << std::endl;
         std::cout << separator << "      Result" << std::endl << separator;
        std::cout << lat;
        std::cout << "Merit: " << search->bestMeritValue() << std::endl;
        std::cout << std::endl;
         std::cout << "ELAPSED CPU TIME: " << dt.count() << " seconds" << std::endl << std::endl;

      if (outputFolder != ""){
        std::ofstream outFile;
        std::string fileName = outputFolder + "/output.txt";
        outFile.open(fileName);
        outFile << "# Input Command Line: " << cmd.originalCommandLine << std::endl;
        outFile << "# Merit: " << search->bestMeritValue() << std::endl;
        outFile << "# Parameters for a lattice rule";
        outFile << helper2<ET>(lat.sizeParam());
        outFile << lat.dimension() <<"    # s = "<< lat.dimension() << " dimensions\n";
        outFile << lat.sizeParam().numPoints() <<"    # modulus = n = "<< lat.sizeParam().numPoints() << " points\n";
        auto vec = lat.gen();
        outFile << "# Coordinates of generating vector, starting at j=1" << std::endl;
        for (unsigned int coord = 0; coord < vec.size(); coord++){
          if (coord < vec.size() - 1){
            outFile << vec[coord] << std::endl;
          }
          else{
            outFile << vec[coord];
          }
        }
        outFile.close();
      }

      if (merit_digits_displayed)
   std::cout.precision(old_precision);

      search->reset();
    }
}

template <EmbeddingType ET>
void executePolynomial(const Parser::CommandLine<LatticeType::POLYNOMIAL, ET>& cmd, int verbose, unsigned int repeat, std::string outputFolder, NetBuilder::OutputStyle outputStyle)
{
   const LatticeType LR = LatticeType::POLYNOMIAL ;
   using namespace std::chrono;

   auto search = cmd.parse();

   unsigned int interlacingFactor = 1;
    try{
      interlacingFactor = boost::lexical_cast<unsigned int>(cmd.interlacingFactor);
    }
    catch (boost::bad_lexical_cast&) {}

   const std::string separator = "====================\n";

   std::cout << separator << "    Input" << std::endl << separator << *search << std::endl;
    if (outputFolder != ""){
      std::ofstream outFile;
      std::string fileName = outputFolder + "/input.txt";
      outFile.open(fileName);
      outFile << "Input Command Line: " << cmd.originalCommandLine << std::endl << std::endl;
      outFile << *search;
      outFile.close();
    }

   if (verbose > 0) {
      search->onLatticeSelected().connect(onLatticeSelected<LR,ET>);
      search->setObserverVerbosity(verbose-1);
      search->setVerbose(verbose-2);
   }

   for (unsigned int i = 0; i < repeat; i++) {
        if (repeat > 1){
          std::cout << separator << "      Run " << i+1 << std::endl << separator;
        }
        else{
          std::cout << separator << "Running the task..." << std::endl << separator;
        }

        auto t0 = high_resolution_clock::now();
        search->execute();
        auto t1 = high_resolution_clock::now();

        unsigned int old_precision = (unsigned int) std::cout.precision();
        if (merit_digits_displayed){
          std::cout.precision(merit_digits_displayed);
        }
       const auto lat = search->bestLattice();

        auto dt = duration_cast<duration<double>>(t1 - t0);
           std::cout << std::endl;
           std::cout << separator << "    Result" << std::endl << separator;
           std::cout << lat;
           std::cout << "Merit: " << search->bestMeritValue() << std::endl;
           std::cout << std::endl;
           std::cout << "ELAPSED CPU TIME: " << dt.count() << " seconds" << std::endl << std::endl;

      if (outputFolder != ""){
          NetBuilder::DigitalNet<NetBuilder::NetConstruction::POLYNOMIAL> net((unsigned int) lat.gen().size(), lat.sizeParam().modulus(),lat.gen());

          if (outputStyle != NetBuilder::OutputStyle::TERMINAL){
            std::ofstream outFile;
            std::string fileName = outputFolder + "/output.txt";
            outFile.open(fileName);
            outFile << "# Input Command Line: " << cmd.originalCommandLine << std::endl;
            outFile << "# Merit: " << search->bestMeritValue() << std::endl;
            outFile << net.format(outputStyle, interlacingFactor) ;
            outFile.close();
          }
      }

        if (merit_digits_displayed){
          std::cout.precision(old_precision);
        }

        search->reset();
    }
}

int main(int argc, const char *argv[])
{

   try {
        auto opt = parse(argc, argv);

        // bool quiet = opt.count("quiet");
        int verbose = opt["verbose"].as<int>();

        auto repeat = opt["repeat"].as<unsigned int>();

        std::string outputFolder = "";
        if (opt.count("output-folder") >= 1){
          outputFolder = opt["output-folder"].as<std::string>();
          std::cout << "Writing in output folder: " << outputFolder << std::endl;
          boost::filesystem::create_directories(outputFolder);
        }

        // global variable
        merit_digits_displayed = opt["merit-digits-displayed"].as<unsigned int>();

        std::string outputstyle = opt["output-style"].as<std::string>();

       LatBuilder::LatticeType lattice = Parser::LatticeParser::parse(opt["construction"].as<std::string>());

       std::vector<std::string> all_args;
       if (argc > 1) {
          all_args.assign(argv + 1, argv + argc);
        }

       if(lattice == LatticeType::ORDINARY){

            Parser::CommandLine<LatticeType::ORDINARY, EmbeddingType::MULTILEVEL> cmd;

            cmd.originalCommandLine = boost::algorithm::join(all_args, " ");
            cmd.construction  = opt["exploration-method"].as<std::string>();
            cmd.size          = opt["size-parameter"].as<std::string>();
            cmd.dimension     = opt["dimension"].as<std::string>();
            cmd.normType      = opt["norm-type"].as<std::string>();
            cmd.figure        = opt["figure-of-merit"].as<std::string>();
            cmd.weights       = opt["weights"].as<std::vector<std::string>>();

            if (opt.count("combiner") == 1){
              cmd.combiner      = opt["combiner"].as<std::string>();
            }
            else{
              cmd.combiner = "level:max";
            }

            if (opt["interlacing-factor"].as<std::string>() != "1")
            {
              throw std::runtime_error("Interlacing can only be used with polynomial lattice rules.");
            }
            else
            {
              cmd.interlacingFactor = "1";
            }

            cmd.weightsPowerScale = 1.0;
            if (opt.count("weights-power") >= 1) {
               // assume 1.0 if norm-type is `inf' or anything else
               cmd.weightsPowerScale = 1.0;
               try {
                  // start the value of norm-type as a default
                  if (cmd.normType != "inf")
                     cmd.weightsPowerScale = boost::lexical_cast<Real>(cmd.normType);
               }
               catch (boost::bad_lexical_cast&) {}
               // then scale down according to interpretation of input
               cmd.weightsPowerScale /= opt["weights-power"].as<Real>();
            }

            if (opt.count("filters") >= 1)
               cmd.filters = opt["filters"].as<std::vector<std::string>>();

            EmbeddingType latType = Parser::EmbeddingType::parse(opt["multilevel"].as<std::string>());

            if (latType == EmbeddingType::UNILEVEL){
               executeOrdinary<EmbeddingType::UNILEVEL> (cmd, verbose, repeat, outputFolder);

             }
            else{
               executeOrdinary<EmbeddingType::MULTILEVEL> (cmd, verbose, repeat, outputFolder);

             }
      }

      else if(lattice == LatticeType::POLYNOMIAL){

            Parser::CommandLine<LatticeType::POLYNOMIAL, EmbeddingType::MULTILEVEL> cmd;

            cmd.originalCommandLine = boost::algorithm::join(all_args, " ");
            cmd.construction  = opt["exploration-method"].as<std::string>();
            cmd.size          = opt["size-parameter"].as<std::string>();
            cmd.dimension     = opt["dimension"].as<std::string>();
            cmd.normType      = opt["norm-type"].as<std::string>();
            cmd.figure        = opt["figure-of-merit"].as<std::string>();
            cmd.weights       = opt["weights"].as<std::vector<std::string>>();
            cmd.interlacingFactor = opt["interlacing-factor"].as<std::string>();
            if (opt.count("combiner") == 1){
              cmd.combiner      = opt["combiner"].as<std::string>();
            }
            else{
              cmd.combiner = "level:max";
            }

            cmd.weightsPowerScale = 1.0;
            if (opt.count("weights-power") >= 1) {
               // assume 1.0 if norm-type is `inf' or anything else
               cmd.weightsPowerScale = 1.0;
               try {
                  // start the value of norm-type as a default
                  if (cmd.normType != "inf")
                     cmd.weightsPowerScale = boost::lexical_cast<Real>(cmd.normType);
               }
               catch (boost::bad_lexical_cast&) {}
               // then scale down according to interpretation of input
               cmd.weightsPowerScale /= opt["weights-power"].as<Real>();
            }

            if (opt.count("filters") >= 1)
               cmd.filters = opt["filters"].as<std::vector<std::string>>();

            EmbeddingType latType = Parser::EmbeddingType::parse(opt["multilevel"].as<std::string>());

            NetBuilder::OutputStyle outputStyle = NetBuilder::Parser::OutputStyleParser<NetBuilder::NetConstruction::POLYNOMIAL>::parse(outputstyle);

            if (latType == EmbeddingType::UNILEVEL){
              executePolynomial< EmbeddingType::UNILEVEL> (cmd, verbose, repeat, outputFolder, outputStyle);

             }
            else{
              executePolynomial<EmbeddingType::MULTILEVEL> (cmd, verbose, repeat, outputFolder, outputStyle);

             }
      }
   }
   catch (Parser::ParserError& e) {
      std::cerr << "COMMAND LINE ERROR: " << e.what() << std::endl;
      std::exit(1);
   }
   catch (std::exception& e) {
      std::cerr << "ERROR: " << e.what() << std::endl;
      std::exit(1);
   }

   return 0;
}

}

ext: cc

max_stars_repo_name: YochevedDarmon/latnetbuilder

max_issues_repo_name: YochevedDarmon/latnetbuilder

max_forks_repo_name: YochevedDarmon/latnetbuilder


text:
/*
 * Copyright 2011 Mario Mulansky
 * Copyright 2012 Karsten Ahnert
 *
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or
 * copy at http://www.boost.org/LICENSE_1_0.txt)
 */

#include <boost/array.hpp>

//#include <boost/numeric/odeint/stepper/explicit_generic_rk.hpp>
#include <boost/numeric/odeint/stepper/runge_kutta4.hpp>
#include <boost/numeric/odeint/algebra/array_algebra.hpp>

#include "rk_performance_test_case.hpp"

#include "lorenz.hpp"

using namespace boost::numeric::odeint;

typedef boost::array< double , 3 > state_type;

/*
typedef explicit_generic_rk< 4 , 4 , state_type , double , state_type , double , array_algebra > rk4_type;

typedef rk4_type::coef_a_type coef_a_type;
typedef rk4_type::coef_b_type coef_b_type;
typedef rk4_type::coef_c_type coef_c_type;

const boost::array< double , 1 > a1 = {{ 0.5 }};
const boost::array< double , 2 > a2 = {{ 0.0 , 0.5 }};
const boost::array< double , 3 > a3 = {{ 0.0 , 0.0 , 1.0 }};

const coef_a_type a = fusion::make_vector( a1 , a2 , a3 );
const coef_b_type b = {{ 1.0/6 , 1.0/3 , 1.0/3 , 1.0/6 }};
const coef_c_type c = {{ 0.0 , 0.5 , 0.5 , 1.0 }};
*/

typedef runge_kutta4< state_type , double , state_type , double , array_algebra > rk4_type;

class rk4_wrapper
{

public:

    rk4_wrapper()
    //        : m_stepper( a , b , c )
    {}

    void reset_init_cond()
    {
        m_x[0] = 10.0 * rand() / RAND_MAX;
        m_x[1] = 10.0 * rand() / RAND_MAX;
        m_x[2] = 10.0 * rand() / RAND_MAX;
        m_t = 0.0;
    }

    inline void do_step( const double dt )
    {
        m_stepper.do_step( lorenz(), m_x , m_t , dt );
    }

    double state( const size_t i ) const
    { return m_x[i]; }

private:
    state_type m_x;
    double m_t;
    rk4_type m_stepper;
};

int main()
{
    srand( 12312354 );

    rk4_wrapper stepper;

    run( stepper );
}

max_stars_repo_name: cooparation/caffe-android

max_issues_repo_name: cooparation/caffe-android

max_forks_repo_name: cooparation/caffe-android


text:
// Copyright 2008 by BBN Technologies Corp.
// All Rights Reserved.

#include "Generic/common/leak_detection.h"
#include "Chinese/edt/ch_NameLinkFunctions.h"
#include "Chinese/edt/AliasTable.h"
#include "Generic/theories/SynNode.h"
#include "Generic/theories/Mention.h"
#include "Generic/edt/AbbrevTable.h"
#include "Generic/common/SessionLogger.h"
#include "Generic/common/SymbolHash.h"
#include "Generic/common/UTF8InputStream.h"
#include "Generic/common/UnexpectedInputException.h"
#include "Generic/common/ParamReader.h"
#include <boost/scoped_ptr.hpp>

SymbolHash ChineseNameLinkFunctions::_stopWords(100);
bool ChineseNameLinkFunctions::_is_initialized = false;

bool ChineseNameLinkFunctions::populateAcronyms(const Mention *mention, EntityType linkType) {
	AliasTable *aliasTable = AliasTable::getInstance();

	const size_t MAX_KEY_LENGTH = 250;
	const int MAX_KEY_WORDS = 32;
	const int MAX_ALIASES = 16;
	wchar_t search_key[MAX_KEY_LENGTH];
	Symbol words[MAX_KEY_WORDS], aliases[MAX_ALIASES];
	int i, nAliases = 0;
	size_t key_len = 0;

	int nWords = mention->getHead()->getTerminalSymbols(words, MAX_KEY_WORDS);
	search_key[0] = L'\0';
	for (i = 0; i < nWords && key_len < MAX_KEY_LENGTH; i++) {
		wcscat(search_key, words[i].to_string());
		key_len += wcslen(words[i].to_string());
	}
	if (i < nWords) {
		SessionLogger::warn("name_link") << "ChineseNameLinkFunctions::populateAcronyms(): "
								<< "terminal symbols exceed MAX_KEY_LENGTH\n";
	}

	nAliases = aliasTable->lookup(Symbol(search_key), aliases, MAX_ALIASES);

	if (nAliases > 0) {
		for (i = 0; i < nAliases; i++) {
			AbbrevTable::add(&aliases[i], 1, words, nWords);
		}
	}

	return (nAliases > 0);

}

void ChineseNameLinkFunctions::destroyDataStructures() {
	AliasTable::destroyInstance();
}

void ChineseNameLinkFunctions::recomputeCounts(CountsTable &inTable,
										CountsTable &outTable,
										int &outTotalCount)
{
	// Default behavior: just recopy counts from inTable.
	// No need to resolveSymbols in AbbrevTable to recompute
	// because we don't want to back resolve (link a name
	// to a *previously* seen potential short form).
	outTotalCount = 0;
	outTable.cleanup();
	for(CountsTable::iterator iterator = inTable.begin(); iterator!=inTable.end(); ++iterator) {
		Symbol thisWord = iterator.value().first;
		int thisCount = iterator.value().second;
		outTable.add(thisWord, thisCount);
		outTotalCount += thisCount;
	}
}

int ChineseNameLinkFunctions::getLexicalItems(Symbol words[], int nWords,
									   Symbol results[],  int max_results)
{
	int nResults = 0;
	wchar_t sym[2];
	sym[1] = L'\0';

	if (!_is_initialized) {

		std::string file = ParamReader::getRequiredParam("stopword_file");
		loadStopWords(file.c_str());
		_is_initialized = true;
	}

	for (int i = 0; i < nWords; i++) {
		const wchar_t* word = words[i].to_string();
		for (int j = 0; word[j] != '\0'; j++) {
			if (nResults == max_results) {
				SessionLogger::warn("name_link") << "ChineseNameLinkFunctions::getLexicalItems(): "
					<< "number of lexical items exceeds max_results: truncating.\n";
				break;
			}
			sym[0] = word[j];
			Symbol s = Symbol(sym);
			if (_stopWords.lookup(s))
				continue;
			results[nResults++] = s;
		}
	}

	return nResults;
}

void ChineseNameLinkFunctions::loadStopWords(const char *file) {
	boost::scoped_ptr<UTF8InputStream> stream_scoped_ptr(UTF8InputStream::build(file));
	UTF8InputStream& stream(*stream_scoped_ptr);
	int size = -1;
	stream >> size;
	if (size < 0)
		throw UnexpectedInputException("NameLinkerTrainer::loadStopWords()",
									   "couldn't read size of stopWord array");

	UTF8Token token;
	int i;
	for (i = 0; i < size; i++) {
		stream >> token;
		_stopWords.add(token.symValue());
	}
}

max_stars_repo_name: BBN-E/serif

max_issues_repo_name: BBN-E/serif

max_forks_repo_name: BBN-E/serif


text:
#include "STIPNode.h"

#include <Eigen/Core>

#include <boost/timer.hpp>

#include <iostream>
#include <numeric>

namespace nuisken {
namespace randomforests {

STIPNode::MeasureType STIPNode::decideType() {
    std::uniform_int_distribution<> distribution(0, 1);
    int typeNumber = distribution(RandomGenerator::getInstance().generator_);
    switch (typeNumber) {
        case 0:
            return CLASS;
        case 1:
            return VECTOR;
        default:
            return CLASS;
    }
}

STIPSplitParameters STIPNode::generateRandomParameter() {
    std::uniform_int_distribution<> channelDistribution(0, numberOfFeatureChannels - 1);
    int featureChannel = channelDistribution(RandomGenerator::getInstance().generator_);

    std::uniform_int_distribution<> indexDistribution(
            0, numberOfFeatureDimensions.at(featureChannel) - 1);
    int index1 = indexDistribution(RandomGenerator::getInstance().generator_);
    // int index2;
    // do {
    int index2 = indexDistribution(RandomGenerator::getInstance().generator_);
    //} while (index1 == index2);

    return STIPSplitParameters(index1, index2, featureChannel);
}

double STIPNode::evaluateSplit(const std::vector<FeatureRawPtr>& leftFeatures,
                               const std::vector<FeatureRawPtr>& rightFeatures) const {
    auto leftValue = 0.0;
    auto rightValue = 0.0;

    switch (type) {
        case CLASS:
            leftValue = calculateClassUncertainty(leftFeatures);
            rightValue = calculateClassUncertainty(rightFeatures);
            break;
        case VECTOR:
            leftValue = calculateVectorUncertainty(leftFeatures);
            rightValue = calculateVectorUncertainty(rightFeatures);
            break;
    }

    return (leftValue + rightValue) / (leftFeatures.size() + rightFeatures.size());
}

double STIPNode::calculateClassUncertainty(const std::vector<FeatureRawPtr>& features) const {
    //各クラスの割合を計算
    Eigen::VectorXd classProbabilities = Eigen::VectorXd::Zero(numberOfClasses);
    auto oneProbability = 1.0 / features.size();
    for (const auto& feature : features) {
        classProbabilities(feature->getClassLabel()) += oneProbability;
    }

    //曖昧さ（エントロピー）を計算
    double uncertainty = 0.0;
    for (auto i = 0; i < classProbabilities.size(); ++i) {
        if (0.0 != classProbabilities(i)) {
            uncertainty += classProbabilities(i) * std::log(classProbabilities(i));
        }
    }
    uncertainty *= static_cast<double>(features.size());

    return uncertainty;
}

double STIPNode::calculateVectorUncertainty(const std::vector<FeatureRawPtr>& features) const {
    // displacementVectorの平均を計算
    std::vector<cv::Vec3f> meanDisplacementVectors(numberOfClasses);
    Eigen::VectorXi sizes = Eigen::VectorXi::Zero(numberOfClasses);

    auto end = std::end(features);
    for (auto itr = std::begin(features); itr != end; ++itr) {
        auto displacementVector = (*itr)->getDisplacementVector();
        auto classLabel = (*itr)->getClassLabel();

        meanDisplacementVectors.at(classLabel) += displacementVector;

        ++sizes(classLabel);
    }
    for (auto i = 0; i < numberOfClasses; ++i) {
        meanDisplacementVectors.at(i) /= static_cast<double>(sizes(i));
    }

    //曖昧さを計算
    auto uncertainty = 0.0;
    for (auto itr = std::begin(features); itr != end; ++itr) {
        // cv::Vec3iをcv::Vec3fに変換
        cv::Vec3f displacementVector((*itr)->getDisplacementVector());
        auto difference = displacementVector - meanDisplacementVectors.at((*itr)->getClassLabel());

        uncertainty += cv::norm(difference);
    }

    return -uncertainty;
}

bool STIPNode::decision(const FeatureRawPtr& feature, const STIPSplitParameters& splitParameter,
                        double tau) const {
    double value1 = feature->getFeatureValue(splitParameter.getIndex1(),
                                             splitParameter.getFeatureChannel());
    double value2 = feature->getFeatureValue(splitParameter.getIndex2(),
                                             splitParameter.getFeatureChannel());

    if (value1 < (value2 + tau)) {
        return true;
    } else {
        return false;
    }
}

std::shared_ptr<STIPLeaf> STIPNode::calculateLeafData(
        const std::vector<FeatureRawPtr>& features) const {
    std::vector<STIPLeaf::FeatureInfo> featureInfo;

    auto end = std::end(features);
    for (auto itr = std::begin(features); itr != end; ++itr) {
        featureInfo.emplace_back((*itr)->getIndex(), (*itr)->getClassLabel(),
                                 (*itr)->getSpatialScale(), (*itr)->getTemporalScale(),
                                 (*itr)->getDisplacementVector());
    }

    return std::make_shared<STIPLeaf>(featureInfo);
}

std::shared_ptr<STIPLeaf> STIPNode::loadLeafData(std::queue<std::string>& nodeElements) const {
    auto leaf = std::make_shared<STIPLeaf>();
    leaf->load(nodeElements);

    return leaf;
}
}
}