<commit_before>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "command.h"
#include "header.h"
#include "image.h"
#include "phase_encoding.h"
#include "algo/threaded_loop.h"
#include "dwi/gradient.h"
#include "dwi/shells.h"
#include "dwi/sdeconv/csd.h"
#include "dwi/sdeconv/msmt_csd.h"
#include "math/SH.h"

using namespace MR;
using namespace App;

const char* const algorithms[] = { "csd", "msmt_csd", NULL };

OptionGroup CommonOptions = OptionGroup ("Options common to more than one algorithm")

    + Option ("directions",
              "specify the directions over which to apply the non-negativity constraint "
              "(by default, the built-in 300 direction set is used). These should be "
              "supplied as a text file containing [ az el ] pairs for the directions.")
      + Argument ("file").type_file_in()

    + Option ("lmax",
              "the maximum spherical harmonic order for the output FOD(s)."
              "For algorithms with multiple outputs, this should be "
              "provided as a comma-separated list of integers, one for "
              "each output image; for single-output algorithms, only "
              "a single integer should be provided. If omitted, the "
              "command will use the highest possible lmax given the "
              "diffusion gradient table, up to a maximum of 8.")
      + Argument ("order").type_sequence_int()

    + Option ("mask",
              "only perform computation within the specified binary brain mask image.")
      + Argument ("image").type_image_in();

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com) and Ben Jeurissen (ben.jeurissen@uantwerpen.be)";

  SYNOPSIS = "Estimate fibre orientation distributions from diffusion data using spherical deconvolution";

  DESCRIPTION
    + Math::SH::encoding_description;

  EXAMPLES
    + Example ("Perform single-shell single-tissue CSD",
               "dwi2fod csd dwi.mif response_wm.txt wmfod.mif",
               "This algorithm is designed for single-shell data and only uses a single "
               "b-value. The response function text file provided should only contain a "
               "a single row, corresponding to the b-value used for CSD.")

    + Example ("Perform multi-shell multi-tissue CSD",
               "dwi2fod msmt_csd dwi.mif response_wm.txt wmfod.mif response_gm.txt gm.mif response_csf.txt csf.mif",
               "This example is the most common use case of multi-tissue CSD, estimating "
               "a white matter FOD, and grey matter and CSF compartments. This algorithm "
               "requires at least three unique b-values to estimate three tissue compartments. "
               "Each response function text file should have a number of rows equal to the "
               "number of b-values used. If only two unique b-values are available, it's also "
               "possible to estimate only two tissue compartments, e.g., white matter and CSF.");

  REFERENCES
    + "* If using csd algorithm:\n"
    "Tournier, J.-D.; Calamante, F. & Connelly, A. " // Internal
    "Robust determination of the fibre orientation distribution in diffusion MRI: "
    "Non-negativity constrained super-resolved spherical deconvolution. "
    "NeuroImage, 2007, 35, 1459-1472"

    + "* If using msmt_csd algorithm:\n"
    "Jeurissen, B; Tournier, J-D; Dhollander, T; Connelly, A & Sijbers, J. " // Internal
    "Multi-tissue constrained spherical deconvolution for improved analysis of multi-shell diffusion MRI data "
    "NeuroImage, 2014, 103, 411-426"

    + "Tournier, J.-D.; Calamante, F., Gadian, D.G. & Connelly, A. " // Internal
    "Direct estimation of the fiber orientation density function from "
    "diffusion-weighted MRI data using spherical deconvolution."
    "NeuroImage, 2004, 23, 1176-1185";

  ARGUMENTS
    + Argument ("algorithm", "the algorithm to use for FOD estimation. "
                             "(options are: " + join(algorithms, ",") + ")").type_choice (algorithms)
    + Argument ("dwi", "the input diffusion-weighted image").type_image_in()
    + Argument ("response odf", "pairs of input tissue response and output ODF images").allow_multiple();

  OPTIONS
    + DWI::GradImportOptions()
    + DWI::ShellsOption
    + CommonOptions
    + DWI::SDeconv::CSD_options
    + DWI::SDeconv::MSMT_CSD_options
    + Stride::Options;
}

class CSD_Processor { MEMALIGN(CSD_Processor)
  public:
    CSD_Processor (const DWI::SDeconv::CSD::Shared& shared, Image<bool>& mask) :
      sdeconv (shared),
      data (shared.dwis.size()),
      mask (mask) { }

    void operator () (Image<float>& dwi, Image<float>& fod) {
      if (!load_data (dwi)) {
        for (auto l = Loop (3) (fod); l; ++l)
          fod.value() = 0.0;
        return;
      }

      sdeconv.set (data);

      size_t n;
      for (n = 0; n < sdeconv.shared.niter; n++)
        if (sdeconv.iterate())
          break;

      if (sdeconv.shared.niter && n >= sdeconv.shared.niter)
        INFO ("voxel [ " + str (dwi.index(0)) + " " + str (dwi.index(1)) + " " + str (dwi.index(2)) +
            " ] did not reach full convergence");

      fod.row(3) = sdeconv.FOD();
    }

  private:
    DWI::SDeconv::CSD sdeconv;
    Eigen::VectorXd data;
    Image<bool> mask;

    bool load_data (Image<float>& dwi) {
      if (mask.valid()) {
        assign_pos_of (dwi, 0, 3).to (mask);
        if (!mask.value())
          return false;
      }

      for (size_t n = 0; n < sdeconv.shared.dwis.size(); n++) {
        dwi.index(3) = sdeconv.shared.dwis[n];
        data[n] = dwi.value();
        if (!std::isfinite (data[n]))
          return false;
        if (data[n] < 0.0)
          data[n] = 0.0;
      }

      return true;
    }

};

class MSMT_Processor { MEMALIGN (MSMT_Processor)
  public:
    MSMT_Processor (const DWI::SDeconv::MSMT_CSD::Shared& shared, Image<bool>& mask_image,
      vector< Image<float> > odf_images, Image<float> dwi_modelled = Image<float>()) :
        sdeconv (shared),
        mask_image (mask_image),
        odf_images (odf_images),
        modelled_image (dwi_modelled),
        dwi_data (shared.grad.rows()),
        output_data (shared.problem.H.cols()) { }

    void operator() (Image<float>& dwi_image)
    {
      if (mask_image.valid()) {
        assign_pos_of (dwi_image, 0, 3).to (mask_image);
        if (!mask_image.value())
          return;
      }

      dwi_data = dwi_image.row(3);

      sdeconv (dwi_data, output_data);
      if (sdeconv.niter >= sdeconv.shared.problem.max_niter) {
        INFO ("voxel [ " + str (dwi_image.index(0)) + " " + str (dwi_image.index(1)) + " " + str (dwi_image.index(2)) +
            " ] did not reach full convergence");
      }

      size_t j = 0;
      for (size_t i = 0; i < odf_images.size(); ++i) {
        assign_pos_of (dwi_image, 0, 3).to (odf_images[i]);
        for (auto l = Loop(3)(odf_images[i]); l; ++l)
          odf_images[i].value() = output_data[j++];
      }

      if (modelled_image.valid()) {
        assign_pos_of (dwi_image, 0, 3).to (modelled_image);
        dwi_data = sdeconv.shared.problem.H * output_data;
        modelled_image.row(3) = dwi_data;
      }
    }

  private:
    DWI::SDeconv::MSMT_CSD sdeconv;
    Image<bool> mask_image;
    vector< Image<float> > odf_images;
    Image<float> modelled_image;
    Eigen::VectorXd dwi_data;
    Eigen::VectorXd output_data;
};

void run ()
{

  auto header_in = Header::open (argument[1]);
  Header header_out (header_in);
  header_out.ndim() = 4;
  header_out.datatype() = DataType::Float32;
  header_out.datatype().set_byte_order_native();
  Stride::set_from_command_line (header_out, Stride::contiguous_along_axis (3, header_in));

  auto mask = Image<bool>();
  auto opt = get_options ("mask");
  if (opt.size()) {
    mask = Header::open (opt[0][0]).get_image<bool>();
    check_dimensions (header_in, mask, 0, 3);
  }

  int algorithm = argument[0];
  if (algorithm == 0) {

    if (argument.size() != 4)
      throw Exception ("CSD algorithm expects a single input response function and single output FOD image");

    DWI::SDeconv::CSD::Shared shared (header_in);
    shared.parse_cmdline_options();
    try {
      shared.set_response (argument[2]);
    } catch (Exception& e) {
      throw Exception (e, "CSD algorithm expects second argument to be the input response function file");
    }

    shared.init();

    header_out.size(3) = shared.nSH();
    DWI::stash_DW_scheme (header_out, shared.grad);
    PhaseEncoding::clear_scheme (header_out);
    auto fod = Image<float>::create (argument[3], header_out);

    CSD_Processor processor (shared, mask);
    auto dwi = header_in.get_image<float>().with_direct_io (3);
    ThreadedLoop ("performing constrained spherical deconvolution", dwi, 0, 3)
        .run (processor, dwi, fod);

  } else if (algorithm == 1) {

    if (argument.size() % 2)
      throw Exception ("MSMT_CSD algorithm expects pairs of (input response function & output FOD image) to be provided");

    DWI::SDeconv::MSMT_CSD::Shared shared (header_in);
    shared.parse_cmdline_options();

    const size_t num_tissues = (argument.size()-2)/2;
    vector<std::string> response_paths;
    vector<std::string> odf_paths;
    for (size_t i = 0; i < num_tissues; ++i) {
      response_paths.push_back (argument[i*2+2]);
      odf_paths.push_back (argument[i*2+3]);
    }

    try {
      shared.set_responses (response_paths);
    } catch (Exception& e) {
      throw Exception (e, "MSMT_CSD algorithm expects the first file in each argument pair to be an input response function file");
    }

    shared.init();

    DWI::stash_DW_scheme (header_out, shared.grad);

    vector< Image<float> > odfs;
    for (size_t i = 0; i < num_tissues; ++i) {
      header_out.size (3) = Math::SH::NforL (shared.lmax[i]);
      odfs.push_back (Image<float> (Image<float>::create (odf_paths[i], header_out)));
    }

    Image<float> dwi_modelled;
    auto opt = get_options ("predicted_signal");
    if (opt.size())
      dwi_modelled = Image<float>::create (opt[0][0], header_in);

    MSMT_Processor processor (shared, mask, odfs, dwi_modelled);
    auto dwi = header_in.get_image<float>().with_direct_io (3);
    ThreadedLoop ("performing multi-shell, multi-tissue CSD", dwi, 0, 3)
        .run (processor, dwi);

  } else {
    assert (0);
  }

}

<commit_msg>dwi2fod: update documentation around default for lmax<commit_after>/* Copyright (c) 2008-2019 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include "command.h"
#include "header.h"
#include "image.h"
#include "phase_encoding.h"
#include "algo/threaded_loop.h"
#include "dwi/gradient.h"
#include "dwi/shells.h"
#include "dwi/sdeconv/csd.h"
#include "dwi/sdeconv/msmt_csd.h"
#include "math/SH.h"

using namespace MR;
using namespace App;

const char* const algorithms[] = { "csd", "msmt_csd", NULL };

OptionGroup CommonOptions = OptionGroup ("Options common to more than one algorithm")

    + Option ("directions",
              "specify the directions over which to apply the non-negativity constraint "
              "(by default, the built-in 300 direction set is used). These should be "
              "supplied as a text file containing [ az el ] pairs for the directions.")
      + Argument ("file").type_file_in()

    + Option ("lmax",
              "the maximum spherical harmonic order for the output FOD(s)."
              "For algorithms with multiple outputs, this should be "
              "provided as a comma-separated list of integers, one for "
              "each output image; for single-output algorithms, only "
              "a single integer should be provided. If omitted, the "
              "command will use the lmax of the corresponding response "
              "function (i.e based on its number of coefficients), "
              "up to a maximum of 8.")
      + Argument ("order").type_sequence_int()

    + Option ("mask",
              "only perform computation within the specified binary brain mask image.")
      + Argument ("image").type_image_in();

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com) and Ben Jeurissen (ben.jeurissen@uantwerpen.be)";

  SYNOPSIS = "Estimate fibre orientation distributions from diffusion data using spherical deconvolution";

  DESCRIPTION
    + Math::SH::encoding_description;

  EXAMPLES
    + Example ("Perform single-shell single-tissue CSD",
               "dwi2fod csd dwi.mif response_wm.txt wmfod.mif",
               "This algorithm is designed for single-shell data and only uses a single "
               "b-value. The response function text file provided should only contain a "
               "a single row, corresponding to the b-value used for CSD.")

    + Example ("Perform multi-shell multi-tissue CSD",
               "dwi2fod msmt_csd dwi.mif response_wm.txt wmfod.mif response_gm.txt gm.mif response_csf.txt csf.mif",
               "This example is the most common use case of multi-tissue CSD, estimating "
               "a white matter FOD, and grey matter and CSF compartments. This algorithm "
               "requires at least three unique b-values to estimate three tissue compartments. "
               "Each response function text file should have a number of rows equal to the "
               "number of b-values used. If only two unique b-values are available, it's also "
               "possible to estimate only two tissue compartments, e.g., white matter and CSF.");

  REFERENCES
    + "* If using csd algorithm:\n"
    "Tournier, J.-D.; Calamante, F. & Connelly, A. " // Internal
    "Robust determination of the fibre orientation distribution in diffusion MRI: "
    "Non-negativity constrained super-resolved spherical deconvolution. "
    "NeuroImage, 2007, 35, 1459-1472"

    + "* If using msmt_csd algorithm:\n"
    "Jeurissen, B; Tournier, J-D; Dhollander, T; Connelly, A & Sijbers, J. " // Internal
    "Multi-tissue constrained spherical deconvolution for improved analysis of multi-shell diffusion MRI data "
    "NeuroImage, 2014, 103, 411-426"

    + "Tournier, J.-D.; Calamante, F., Gadian, D.G. & Connelly, A. " // Internal
    "Direct estimation of the fiber orientation density function from "
    "diffusion-weighted MRI data using spherical deconvolution."
    "NeuroImage, 2004, 23, 1176-1185";

  ARGUMENTS
    + Argument ("algorithm", "the algorithm to use for FOD estimation. "
                             "(options are: " + join(algorithms, ",") + ")").type_choice (algorithms)
    + Argument ("dwi", "the input diffusion-weighted image").type_image_in()
    + Argument ("response odf", "pairs of input tissue response and output ODF images").allow_multiple();

  OPTIONS
    + DWI::GradImportOptions()
    + DWI::ShellsOption
    + CommonOptions
    + DWI::SDeconv::CSD_options
    + DWI::SDeconv::MSMT_CSD_options
    + Stride::Options;
}

class CSD_Processor { MEMALIGN(CSD_Processor)
  public:
    CSD_Processor (const DWI::SDeconv::CSD::Shared& shared, Image<bool>& mask) :
      sdeconv (shared),
      data (shared.dwis.size()),
      mask (mask) { }

    void operator () (Image<float>& dwi, Image<float>& fod) {
      if (!load_data (dwi)) {
        for (auto l = Loop (3) (fod); l; ++l)
          fod.value() = 0.0;
        return;
      }

      sdeconv.set (data);

      size_t n;
      for (n = 0; n < sdeconv.shared.niter; n++)
        if (sdeconv.iterate())
          break;

      if (sdeconv.shared.niter && n >= sdeconv.shared.niter)
        INFO ("voxel [ " + str (dwi.index(0)) + " " + str (dwi.index(1)) + " " + str (dwi.index(2)) +
            " ] did not reach full convergence");

      fod.row(3) = sdeconv.FOD();
    }

  private:
    DWI::SDeconv::CSD sdeconv;
    Eigen::VectorXd data;
    Image<bool> mask;

    bool load_data (Image<float>& dwi) {
      if (mask.valid()) {
        assign_pos_of (dwi, 0, 3).to (mask);
        if (!mask.value())
          return false;
      }

      for (size_t n = 0; n < sdeconv.shared.dwis.size(); n++) {
        dwi.index(3) = sdeconv.shared.dwis[n];
        data[n] = dwi.value();
        if (!std::isfinite (data[n]))
          return false;
        if (data[n] < 0.0)
          data[n] = 0.0;
      }

      return true;
    }

};

class MSMT_Processor { MEMALIGN (MSMT_Processor)
  public:
    MSMT_Processor (const DWI::SDeconv::MSMT_CSD::Shared& shared, Image<bool>& mask_image,
      vector< Image<float> > odf_images, Image<float> dwi_modelled = Image<float>()) :
        sdeconv (shared),
        mask_image (mask_image),
        odf_images (odf_images),
        modelled_image (dwi_modelled),
        dwi_data (shared.grad.rows()),
        output_data (shared.problem.H.cols()) { }

    void operator() (Image<float>& dwi_image)
    {
      if (mask_image.valid()) {
        assign_pos_of (dwi_image, 0, 3).to (mask_image);
        if (!mask_image.value())
          return;
      }

      dwi_data = dwi_image.row(3);

      sdeconv (dwi_data, output_data);
      if (sdeconv.niter >= sdeconv.shared.problem.max_niter) {
        INFO ("voxel [ " + str (dwi_image.index(0)) + " " + str (dwi_image.index(1)) + " " + str (dwi_image.index(2)) +
            " ] did not reach full convergence");
      }

      size_t j = 0;
      for (size_t i = 0; i < odf_images.size(); ++i) {
        assign_pos_of (dwi_image, 0, 3).to (odf_images[i]);
        for (auto l = Loop(3)(odf_images[i]); l; ++l)
          odf_images[i].value() = output_data[j++];
      }

      if (modelled_image.valid()) {
        assign_pos_of (dwi_image, 0, 3).to (modelled_image);
        dwi_data = sdeconv.shared.problem.H * output_data;
        modelled_image.row(3) = dwi_data;
      }
    }

  private:
    DWI::SDeconv::MSMT_CSD sdeconv;
    Image<bool> mask_image;
    vector< Image<float> > odf_images;
    Image<float> modelled_image;
    Eigen::VectorXd dwi_data;
    Eigen::VectorXd output_data;
};

void run ()
{

  auto header_in = Header::open (argument[1]);
  Header header_out (header_in);
  header_out.ndim() = 4;
  header_out.datatype() = DataType::Float32;
  header_out.datatype().set_byte_order_native();
  Stride::set_from_command_line (header_out, Stride::contiguous_along_axis (3, header_in));

  auto mask = Image<bool>();
  auto opt = get_options ("mask");
  if (opt.size()) {
    mask = Header::open (opt[0][0]).get_image<bool>();
    check_dimensions (header_in, mask, 0, 3);
  }

  int algorithm = argument[0];
  if (algorithm == 0) {

    if (argument.size() != 4)
      throw Exception ("CSD algorithm expects a single input response function and single output FOD image");

    DWI::SDeconv::CSD::Shared shared (header_in);
    shared.parse_cmdline_options();
    try {
      shared.set_response (argument[2]);
    } catch (Exception& e) {
      throw Exception (e, "CSD algorithm expects second argument to be the input response function file");
    }

    shared.init();

    header_out.size(3) = shared.nSH();
    DWI::stash_DW_scheme (header_out, shared.grad);
    PhaseEncoding::clear_scheme (header_out);
    auto fod = Image<float>::create (argument[3], header_out);

    CSD_Processor processor (shared, mask);
    auto dwi = header_in.get_image<float>().with_direct_io (3);
    ThreadedLoop ("performing constrained spherical deconvolution", dwi, 0, 3)
        .run (processor, dwi, fod);

  } else if (algorithm == 1) {

    if (argument.size() % 2)
      throw Exception ("MSMT_CSD algorithm expects pairs of (input response function & output FOD image) to be provided");

    DWI::SDeconv::MSMT_CSD::Shared shared (header_in);
    shared.parse_cmdline_options();

    const size_t num_tissues = (argument.size()-2)/2;
    vector<std::string> response_paths;
    vector<std::string> odf_paths;
    for (size_t i = 0; i < num_tissues; ++i) {
      response_paths.push_back (argument[i*2+2]);
      odf_paths.push_back (argument[i*2+3]);
    }

    try {
      shared.set_responses (response_paths);
    } catch (Exception& e) {
      throw Exception (e, "MSMT_CSD algorithm expects the first file in each argument pair to be an input response function file");
    }

    shared.init();

    DWI::stash_DW_scheme (header_out, shared.grad);

    vector< Image<float> > odfs;
    for (size_t i = 0; i < num_tissues; ++i) {
      header_out.size (3) = Math::SH::NforL (shared.lmax[i]);
      odfs.push_back (Image<float> (Image<float>::create (odf_paths[i], header_out)));
    }

    Image<float> dwi_modelled;
    auto opt = get_options ("predicted_signal");
    if (opt.size())
      dwi_modelled = Image<float>::create (opt[0][0], header_in);

    MSMT_Processor processor (shared, mask, odfs, dwi_modelled);
    auto dwi = header_in.get_image<float>().with_direct_io (3);
    ThreadedLoop ("performing multi-shell, multi-tissue CSD", dwi, 0, 3)
        .run (processor, dwi);

  } else {
    assert (0);
  }

}

<|endoftext|>


<commit_before>#include <fstream>
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

bool writeBug = false;
bool writeFileNames = false;

string patStr;
string tesStr;

bool isWhite(char _c)
{
	if (_c == ' ' || _c == '	' || _c == '\n')
		return true;
	else
		return false;
}

bool readNext(ifstream &_file, string &_str)
{
	while(isWhite(_file.peek()))
		_file.get();
	if (_file.eof() == false)
	{
		_file >> _str;
		return true;
	}
	else
		return false;
}

int main(int _argc, char *_argv[])
{
	for (int i = 1; i < _argc; i++)
	{
		if (_argv[i][0] != '-')
		{
			if (i + 1 < _argc)
			{
				patStr = string(_argv[i]);
				tesStr = string(_argv[i + 1]);
				break;
			}
			else
			{
				cerr << "CMP: cmp/default: No second output file path" << endl;
				return -2;
			}
		}
		else
		{
			if (strcmp(_argv[i], "-bug") == 0)
				writeBug = true;
			else if (strcmp(_argv[i], "-fname") == 0)
				writeFileNames = true;
			else
			{
				cerr << "CMP: No arg called \"" << _argv[i] << "\" exists" << endl;
			}
		}
	}
	if (writeFileNames)
		cout << patStr << "	" << tesStr << endl;

	ifstream pat(patStr.c_str());
	ifstream tes(tesStr.c_str());

	if (pat.is_open() == false)
	{
		cerr << "CMP: Can't open:" << patStr << endl;
		return -2;
	}
	if (tes.is_open() == false)
	{
		cerr << "CMP: Can't open: " << tesStr << endl;
		return -2;
	}

	int strNr = 1;
	bool pb, tb;
	while (true)
	{
		pb = readNext(pat, patStr);
		tb = readNext(tes, tesStr);

		if (pb == false && tb == false)
			break;
		else if (pb == false || tb == false)
		{
			if (writeBug)
				cout << (pb == false ? "Output file is too long" : "Output file is too short") << endl;

			pat.close();
			tes.close();
			return -1;
		}

		if (patStr != tesStr)
		{
			if (writeBug)
			{
				pat.close();
				tes.close();
				cout << "String:" << strNr << " Expected:" << patStr << " Readed:" << tesStr << endl;
			}
			return -1;
		}

		strNr++;
	}
	pat.close();
	tes.close();
	return 0;
}
<commit_msg>DOS/Windows line ending support for cmp/default.cpp<commit_after>#include <fstream>
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

bool writeBug = false;
bool writeFileNames = false;

string patStr;
string tesStr;

bool isWhite(char _c)
{
	if (_c == ' ' || _c == '	' || _c == '\n' || _c == '\r')
		return true;
	else
		return false;
}

bool readNext(ifstream &_file, string &_str)
{
	while(isWhite(_file.peek()))
		_file.get();
	if (_file.eof() == false)
	{
		_file >> _str;
		return true;
	}
	else
		return false;
}

int main(int _argc, char *_argv[])
{
	for (int i = 1; i < _argc; i++)
	{
		if (_argv[i][0] != '-')
		{
			if (i + 1 < _argc)
			{
				patStr = string(_argv[i]);
				tesStr = string(_argv[i + 1]);
				break;
			}
			else
			{
				cerr << "CMP: cmp/default: No second output file path" << endl;
				return -2;
			}
		}
		else
		{
			if (strcmp(_argv[i], "-bug") == 0)
				writeBug = true;
			else if (strcmp(_argv[i], "-fname") == 0)
				writeFileNames = true;
			else
			{
				cerr << "CMP: No arg called \"" << _argv[i] << "\" exists" << endl;
			}
		}
	}
	if (writeFileNames)
		cout << patStr << "	" << tesStr << endl;

	ifstream pat(patStr.c_str());
	ifstream tes(tesStr.c_str());

	if (pat.is_open() == false)
	{
		cerr << "CMP: Can't open:" << patStr << endl;
		return -2;
	}
	if (tes.is_open() == false)
	{
		cerr << "CMP: Can't open: " << tesStr << endl;
		return -2;
	}

	int strNr = 1;
	bool pb, tb;
	while (true)
	{
		pb = readNext(pat, patStr);
		tb = readNext(tes, tesStr);

		if (pb == false && tb == false)
			break;
		else if (pb == false || tb == false)
		{
			if (writeBug)
				cout << (pb == false ? "Output file is too long" : "Output file is too short") << endl;

			pat.close();
			tes.close();
			return -1;
		}

		if (patStr != tesStr)
		{
			if (writeBug)
			{
				pat.close();
				tes.close();
				cout << "String:" << strNr << " Expected:" << patStr << " Readed:" << tesStr << endl;
			}
			return -1;
		}

		strNr++;
	}
	pat.close();
	tes.close();
	return 0;
}
<|endoftext|>


<commit_before>#include "dialogs.h"
#include <cmath>

namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
  template <typename Functor>
  struct functor_trait<Functor, false> {
    typedef decltype (::sigc::mem_fun(std::declval<Functor&>(),
                                      &Functor::operator())) _intermediate;
    typedef typename _intermediate::result_type result_type;
    typedef Functor functor_type;
  };
#else
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
#endif
}

Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_NONE, true) {
  auto g_application=g_application_get_default();
  auto gio_application=Glib::wrap(g_application, true);
  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
  set_transient_for(*application->get_active_window());
  set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);

  show_now();

  while(g_main_context_pending(NULL))
    g_main_context_iteration(NULL, false);
}

std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::string &title,
                        const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
                        Gtk::FileChooserAction gtk_options) {
  Gtk::FileChooserDialog dialog(title, gtk_options);

  auto g_application=g_application_get_default();
  auto gio_application=Glib::wrap(g_application, true);
  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
  dialog.set_transient_for(*application->get_active_window());
  dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);

  if(title=="Save File As")
    gtk_file_chooser_set_filename(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), path.string().c_str());
  else if(!path.empty())
    gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), path.string().c_str());
  else {
    boost::system::error_code ec;
    auto current_path=boost::filesystem::current_path(ec);
    if(!ec)
      gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), current_path.string().c_str());
  }

  dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);

  for (auto &button : buttons)
    dialog.add_button(button.first, button.second);
  return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
}
<commit_msg>Got rid of double dialog.set_position calls in dialogs.cc<commit_after>#include "dialogs.h"
#include <cmath>

namespace sigc {
#ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
  template <typename Functor>
  struct functor_trait<Functor, false> {
    typedef decltype (::sigc::mem_fun(std::declval<Functor&>(),
                                      &Functor::operator())) _intermediate;
    typedef typename _intermediate::result_type result_type;
    typedef Functor functor_type;
  };
#else
  SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE
#endif
}

Dialog::Message::Message(const std::string &text): Gtk::MessageDialog(text, false, Gtk::MessageType::MESSAGE_INFO, Gtk::ButtonsType::BUTTONS_NONE, true) {
  auto g_application=g_application_get_default();
  auto gio_application=Glib::wrap(g_application, true);
  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
  set_transient_for(*application->get_active_window());
  set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);

  show_now();

  while(g_main_context_pending(NULL))
    g_main_context_iteration(NULL, false);
}

std::string Dialog::gtk_dialog(const boost::filesystem::path &path, const std::string &title,
                        const std::vector<std::pair<std::string, Gtk::ResponseType>> &buttons,
                        Gtk::FileChooserAction gtk_options) {
  Gtk::FileChooserDialog dialog(title, gtk_options);

  auto g_application=g_application_get_default();
  auto gio_application=Glib::wrap(g_application, true);
  auto application=Glib::RefPtr<Gtk::Application>::cast_static(gio_application);
  dialog.set_transient_for(*application->get_active_window());
  dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ON_PARENT);

  if(title=="Save File As")
    gtk_file_chooser_set_filename(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), path.string().c_str());
  else if(!path.empty())
    gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), path.string().c_str());
  else {
    boost::system::error_code ec;
    auto current_path=boost::filesystem::current_path(ec);
    if(!ec)
      gtk_file_chooser_set_current_folder(reinterpret_cast<GtkFileChooser*>(dialog.gobj()), current_path.string().c_str());
  }

  for (auto &button : buttons)
    dialog.add_button(button.first, button.second);
  return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : "";
}
<|endoftext|>


<commit_before>// Copyright 2020 Chia Network Inc

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in coiance 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 iied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_BLSSCHEMES_HPP_
#define SRC_BLSSCHEMES_HPP_

#include <iostream>
#include <vector>

#include <relic_conf.h>

#if defined GMP && ARITH == GMP
#include <gmp.h>
#endif

#include "elements.hpp"
#include "privatekey.hpp"

using std::vector;

// These are all MPL schemes
namespace bls {

class Bytes;

class CoreMPL {

public:
    virtual ~CoreMPL() {};
    CoreMPL() = delete;
    CoreMPL(const std::string& strId) : strCiphersuiteId(strId) {}
    // Generates a private key from a seed, similar to HD key generation
    // (hashes the seed), and reduces it mod the group order
    virtual PrivateKey KeyGen(const vector<uint8_t>& seed);
    virtual PrivateKey KeyGen(const Bytes& seed);

    // Generates a public key from a secret key
    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey);

    virtual G1Element SkToG1(const PrivateKey &seckey);

    virtual G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message);
    virtual G2Element Sign(const PrivateKey& seckey, const Bytes& message);

    virtual bool Verify(const vector<uint8_t> &pubkey,
                        const vector<uint8_t> &message,
                        const vector<uint8_t> &signature);

    virtual bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature);

    virtual bool Verify(const G1Element &pubkey,
                        const vector<uint8_t> &message,
                        const G2Element &signature);

    virtual bool Verify(const G1Element& pubkey, const Bytes& message, const G2Element& signature);

    virtual vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures);
    virtual vector<uint8_t> Aggregate(const vector<Bytes>& signatures);

    virtual G2Element Aggregate(const vector<G2Element> &signatures);

    virtual G1Element Aggregate(const vector<G1Element> &publicKeys);

    virtual G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                                      const std::vector<G2Element>& vecSignatures,
                                      const Bytes& message);

    virtual bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                              const G2Element& signature,
                              const Bytes& message);

    virtual bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const vector<uint8_t> &signature);

    virtual bool AggregateVerify(const vector<Bytes>& pubkeys,
                                 const vector<Bytes>& messages,
                                 const Bytes& signature);

    virtual bool AggregateVerify(const vector<G1Element> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const G2Element &signature);

     virtual bool AggregateVerify(const vector<G1Element>& pubkeys,
                                  const vector<Bytes>& messages,
                                  const G2Element& signature);

    PrivateKey DeriveChildSk(const PrivateKey& sk, uint32_t index);
    PrivateKey DeriveChildSkUnhardened(const PrivateKey& sk, uint32_t index);
    G1Element DeriveChildPkUnhardened(const G1Element& sk, uint32_t index);

protected:
    const std::string& strCiphersuiteId;
    bool NativeVerify(g1_t *pubKeys, g2_t *mappedHashes, size_t length);
    G2Element AggregateSecure(std::vector<G1Element> const &vecPublicKeys,
                              std::vector<G2Element> const &vecSignatures,
                              const Bytes& message,
                              bool fLegacy);
    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message,
                      bool fLegacy);
};

class BasicSchemeMPL : public CoreMPL {
public:
    virtual ~BasicSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    BasicSchemeMPL() : CoreMPL(BasicSchemeMPL::CIPHERSUITE_ID) {}
    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class AugSchemeMPL : public CoreMPL {

public:
    virtual ~AugSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    AugSchemeMPL() : CoreMPL(AugSchemeMPL::CIPHERSUITE_ID) {}

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) override;

    G2Element Sign(const PrivateKey& seckey, const Bytes& message) override;

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey &seckey,
                   const vector<uint8_t> &message,
                   const G1Element &prepend_pk);

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey& seckey,
                   const Bytes& message,
                   const G1Element& prepend_pk);

    bool Verify(const vector<uint8_t> &pubkey,
                const vector<uint8_t> &message,
                const vector<uint8_t> &signature) override;

    bool Verify(const Bytes& pubkey,
                const Bytes& message,
                const Bytes& signature) override;

    bool Verify(const G1Element &pubkey,
                const vector<uint8_t> &message,
                const G2Element &signature) override;

    bool Verify(const G1Element& pubkey,
                const Bytes& message,
                const G2Element& signature) override;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class PopSchemeMPL : public CoreMPL {

public:
    virtual ~PopSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    static const std::string POP_CIPHERSUITE_ID;
    PopSchemeMPL() : CoreMPL(PopSchemeMPL::CIPHERSUITE_ID) {}

    G2Element PopProve(const PrivateKey &seckey);

    bool PopVerify(const G1Element &pubkey, const G2Element &signature_proof);

    bool PopVerify(const vector<uint8_t> &pubkey, const vector<uint8_t> &proof);

    bool PopVerify(const Bytes& pubkey, const Bytes& proof);

    bool FastAggregateVerify(const vector<G1Element> &pubkeys,
                             const vector<uint8_t> &message,
                             const G2Element &signature);

    bool FastAggregateVerify(const vector<G1Element>& pubkeys,
                             const Bytes& message,
                             const G2Element& signature);

    bool FastAggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                             const vector<uint8_t> &message,
                             const vector<uint8_t> &signature);

    bool FastAggregateVerify(const vector<Bytes>& pubkeys,
                             const Bytes& message,
                             const Bytes& signature);
};

/**
 * This scheme reflects the Sign/Verify behaviour of older bls-signatures library versions (<0.1.29).
 */
class LegacySchemeMPL : public CoreMPL {

public:
    virtual ~LegacySchemeMPL() {};
    LegacySchemeMPL() : CoreMPL(std::string{}) {}

    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    G2Element Sign(const PrivateKey &seckey, const Bytes& message) final;

    bool Verify(const vector<uint8_t>& pubkey,
                const vector<uint8_t>& message,
                const vector<uint8_t>& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const G1Element& pubkey,
                const vector<uint8_t>& message,
                const G2Element& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    bool Verify(const G1Element &pubkey, const Bytes& message, const G2Element &signature) final;

    vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                              const std::vector<G2Element>& vecSignatures,
                              const Bytes& message) final;

    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message) final;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<Bytes> &pubkeys,
                         const vector<Bytes> &messages,
                         const Bytes &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<Bytes> &messages,
                         const G2Element &signature) final;
};
}  // end namespace bls

#endif  // SRC_BLSSCHEMES_HPP_
<commit_msg>Update schemes.hpp<commit_after>// Copyright 2020 Chia Network Inc

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in coiance 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 iied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_BLSSCHEMES_HPP_
#define SRC_BLSSCHEMES_HPP_

#include <iostream>
#include <vector>

#include <relic_conf.h>

#if defined GMP && ARITH == GMP
#include <gmp.h>
#endif

#include "elements.hpp"
#include "privatekey.hpp"

using std::vector;

// These are all MPL schemes
namespace bls {

class Bytes;

class CoreMPL {

public:
    virtual ~CoreMPL() {};
    CoreMPL() = delete;
    CoreMPL(const std::string& strId) : strCiphersuiteId(strId) {}
    // Generates a private key from a seed, similar to HD key generation
    // (hashes the seed), and reduces it mod the group order
    virtual PrivateKey KeyGen(const vector<uint8_t>& seed);
    virtual PrivateKey KeyGen(const Bytes& seed);

    // Generates a public key from a secret key
    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey);

    virtual G1Element SkToG1(const PrivateKey &seckey);

    virtual G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message);
    virtual G2Element Sign(const PrivateKey& seckey, const Bytes& message);

    virtual bool Verify(const vector<uint8_t> &pubkey,
                        const vector<uint8_t> &message,
                        const vector<uint8_t> &signature);

    virtual bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature);

    virtual bool Verify(const G1Element &pubkey,
                        const vector<uint8_t> &message,
                        const G2Element &signature);

    virtual bool Verify(const G1Element& pubkey, const Bytes& message, const G2Element& signature);

    virtual vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures);
    virtual vector<uint8_t> Aggregate(const vector<Bytes>& signatures);

    virtual G2Element Aggregate(const vector<G2Element> &signatures);

    virtual G1Element Aggregate(const vector<G1Element> &publicKeys);

    virtual G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                                      const std::vector<G2Element>& vecSignatures,
                                      const Bytes& message);

    virtual bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                              const G2Element& signature,
                              const Bytes& message);

    virtual bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const vector<uint8_t> &signature);

    virtual bool AggregateVerify(const vector<Bytes>& pubkeys,
                                 const vector<Bytes>& messages,
                                 const Bytes& signature);

    virtual bool AggregateVerify(const vector<G1Element> &pubkeys,
                                 const vector<vector<uint8_t>> &messages,
                                 const G2Element &signature);

     virtual bool AggregateVerify(const vector<G1Element>& pubkeys,
                                  const vector<Bytes>& messages,
                                  const G2Element& signature);

    PrivateKey DeriveChildSk(const PrivateKey& sk, uint32_t index);
    PrivateKey DeriveChildSkUnhardened(const PrivateKey& sk, uint32_t index);
    G1Element DeriveChildPkUnhardened(const G1Element& sk, uint32_t index);

protected:
    const std::string& strCiphersuiteId;
    bool NativeVerify(g1_t *pubKeys, g2_t *mappedHashes, size_t length);
    G2Element AggregateSecure(std::vector<G1Element> const &vecPublicKeys,
                              std::vector<G2Element> const &vecSignatures,
                              const Bytes& message,
                              bool fLegacy);
    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message,
                      bool fLegacy);
};

class BasicSchemeMPL : public CoreMPL {
public:
    virtual ~BasicSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    BasicSchemeMPL() : CoreMPL(BasicSchemeMPL::CIPHERSUITE_ID) {}
    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class AugSchemeMPL : public CoreMPL {

public:
    virtual ~AugSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    AugSchemeMPL() : CoreMPL(AugSchemeMPL::CIPHERSUITE_ID) {}

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) override;

    G2Element Sign(const PrivateKey& seckey, const Bytes& message) override;

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey &seckey,
                   const vector<uint8_t> &message,
                   const G1Element &prepend_pk);

    // Used for prepending different augMessage
    G2Element Sign(const PrivateKey& seckey,
                   const Bytes& message,
                   const G1Element& prepend_pk);

    bool Verify(const vector<uint8_t> &pubkey,
                const vector<uint8_t> &message,
                const vector<uint8_t> &signature) override;

    bool Verify(const Bytes& pubkey,
                const Bytes& message,
                const Bytes& signature) override;

    bool Verify(const G1Element &pubkey,
                const vector<uint8_t> &message,
                const G2Element &signature) override;

    bool Verify(const G1Element& pubkey,
                const Bytes& message,
                const G2Element& signature) override;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) override;

    bool AggregateVerify(const vector<Bytes>& pubkeys,
                         const vector<Bytes>& messages,
                         const Bytes& signature) override;

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) override;

    bool AggregateVerify(const vector<G1Element>& pubkeys,
                         const vector<Bytes>& messages,
                         const G2Element& signature) override;
};

class PopSchemeMPL : public CoreMPL {

public:
    virtual ~PopSchemeMPL() {};
    static const std::string CIPHERSUITE_ID;
    static const std::string POP_CIPHERSUITE_ID;
    PopSchemeMPL() : CoreMPL(PopSchemeMPL::CIPHERSUITE_ID) {}

    G2Element PopProve(const PrivateKey &seckey);

    bool PopVerify(const G1Element &pubkey, const G2Element &signature_proof);

    bool PopVerify(const vector<uint8_t> &pubkey, const vector<uint8_t> &proof);

    bool PopVerify(const Bytes& pubkey, const Bytes& proof);

    bool FastAggregateVerify(const vector<G1Element> &pubkeys,
                             const vector<uint8_t> &message,
                             const G2Element &signature);

    bool FastAggregateVerify(const vector<G1Element>& pubkeys,
                             const Bytes& message,
                             const G2Element& signature);

    bool FastAggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                             const vector<uint8_t> &message,
                             const vector<uint8_t> &signature);

    bool FastAggregateVerify(const vector<Bytes>& pubkeys,
                             const Bytes& message,
                             const Bytes& signature);
};

/**
 * This scheme reflects the Sign/Verify behaviour of older bls-signatures library versions (<0.1.29).
 */
class LegacySchemeMPL : public CoreMPL {

public:
    virtual ~LegacySchemeMPL() {};
    LegacySchemeMPL() : CoreMPL(std::string{}) {}

    virtual vector<uint8_t> SkToPk(const PrivateKey &seckey) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element Sign(const PrivateKey &seckey, const vector<uint8_t> &message) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    G2Element Sign(const PrivateKey &seckey, const Bytes& message) final;

    bool Verify(const vector<uint8_t>& pubkey,
                const vector<uint8_t>& message,
                const vector<uint8_t>& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const G1Element& pubkey,
                const vector<uint8_t>& message,
                const G2Element& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool Verify(const Bytes& pubkey, const Bytes& message, const Bytes& signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }
    bool Verify(const G1Element &pubkey, const Bytes& message, const G2Element &signature) final;

    virtual vector<uint8_t> Aggregate(const vector<vector<uint8_t>> &signatures) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    G2Element AggregateSecure(const std::vector<G1Element>& vecPublicKeys,
                              const std::vector<G2Element>& vecSignatures,
                              const Bytes& message) final;

    bool VerifySecure(const std::vector<G1Element>& vecPublicKeys,
                      const G2Element& signature,
                      const Bytes& message) final;

    bool AggregateVerify(const vector<vector<uint8_t>> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const vector<uint8_t> &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<Bytes> &pubkeys,
                         const vector<Bytes> &messages,
                         const Bytes &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<vector<uint8_t>> &messages,
                         const G2Element &signature) final { throw std::runtime_error("Not supported in LegacySchemeMPL"); }

    bool AggregateVerify(const vector<G1Element> &pubkeys,
                         const vector<Bytes> &messages,
                         const G2Element &signature) final;
};
}  // end namespace bls

#endif  // SRC_BLSSCHEMES_HPP_
<|endoftext|>


<commit_before>/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#include "base/winlog.h"
#include "base/util/utils.h"

#ifdef _WIN32_WCE
#define FUNAMBOL_HEADER "Funambol Windows Mobile Plug-in Log"
#elif WIN32
#define FUNAMBOL_HEADER "Funambol Win32 Plug-in Log"
#endif

//winLog LOG = winLog(false);

char logmsg[512];

static FILE* logFile = NULL;
static WCHAR wlogDir[512] = TEXT("\\");
static char logName[128] = LOG_NAME;
static char logPath[256] = "\\" ;

winLog::winLog(bool resetLog, const char* path, const char* name) {

    setLogPath(path);
    setLogName(name);

    // MUST use a wchar_t* logDir to manage correctly international chars.
    // If using char* logDir and UTF-8, fopen() is not working correctly and
    // will fail to open the log file. (with UTF-8... why?)
    // So we use _wfopen() and a wchar_t* logDir.
    char logDir[512];
    sprintf(logDir, "%s\\%s", logPath, logName);
    WCHAR* tmp = toWideChar(logDir);
    wcscpy(wlogDir, tmp);
    delete [] tmp;

    //
    // Test to ensure the log file is writable (only if path is set)
    //
    if (path) {
        logFile = _wfopen(wlogDir, TEXT("a+"));
        if (logFile == NULL) {
            WCHAR tmp[512];
            wsprintf(tmp, TEXT("Unable to write log file: \"%s\".\nPlease check your user's permissions."), wlogDir);
            MessageBox(NULL, tmp, TEXT("Funambol"), MB_SETFOREGROUND | MB_OK);
        }
        else {
            fclose(logFile);

            if (resetLog) {
                reset(FUNAMBOL_HEADER);
            }
        }
    }
}

winLog::~winLog() {
    if (logFile != NULL) {
        fclose(logFile);
    }
}

void winLog::setLogPath(const char* configLogPath) {

    if (configLogPath != NULL) {
        sprintf(logPath, "%s", configLogPath);
    } else {
        sprintf(logPath, ".");
    }
    if (logName ){
        char logDir[512];
        sprintf(logDir, "%s\\%s", logPath, logName);
        WCHAR* tmp = toWideChar(logDir);
        wcscpy(wlogDir, tmp);
    }
}

void winLog::setLogName(const char* configLogName) {

    if (configLogName != NULL) {
        sprintf(logName, "%s", configLogName);
    }
    else {
        sprintf(logName, "%s", LOG_NAME);
    }
    if (logPath ){
        char logDir[512];
        sprintf(logDir, "%s\\%s", logPath, logName);
        WCHAR* tmp = toWideChar(logDir);
        wcscpy(wlogDir, tmp);
    }
}

/*
* return a the time to write into log file. If complete is true, it return
* the date too, else only hours, minutes, seconds and milliseconds
*/
static char* createCurrentTime(bool complete) {

    SYSTEMTIME sys_time;
    TIME_ZONE_INFORMATION timezone;
    GetLocalTime(&sys_time);
    GetTimeZoneInformation(&timezone);

    char fmtComplete[] = "%04d-%02d-%02d %02d:%02d:%02d GMT %c%d:%02d";
    char fmt[]         = "%02d:%02d:%02d GMT %c%d:%02d";

    char* ret = new char [64];

    // calculate offset from UTC/GMT in hours:min, positive value
    // means east of Greenwich (e.g. CET = GMT +1)

    char direction = timezone.Bias <= 0 ? '+' : '-';
    int hours = abs(timezone.Bias / 60) ;
    int minutes = abs(timezone.Bias % 60);

    if (complete) {
        sprintf(ret, fmtComplete, sys_time.wYear, sys_time.wMonth, sys_time.wDay,
                 sys_time.wHour, sys_time.wMinute, sys_time.wSecond,
                direction, hours, minutes);
    } else {
        sprintf(ret, fmt, sys_time.wHour, sys_time.wMinute, sys_time.wSecond,
                direction, hours, minutes);
    }
    return ret;
}

void winLog::error(const char*  msg, ...) {
    va_list argList;
    va_start (argList, msg);
    printMessage(LOG_ERROR, msg, argList);
    va_end(argList);
}

void winLog::info(const char*  msg, ...) {
    if (isLoggable(LOG_LEVEL_INFO)) {
        va_list argList;
	    va_start (argList, msg);
        printMessage(LOG_INFO, msg, argList);
	    va_end(argList);

    }
}

void winLog::debug(const char*  msg, ...) {
    if (isLoggable(LOG_LEVEL_DEBUG)) {
	    va_list argList;
        va_start (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        va_end(argList);

    }
}

void winLog::developer(const char*  msg, ...) {
    if (isLoggable(LOG_LEVEL_INFO)) {
        va_list argList;
        va_start (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        va_end(argList);
    }
}

void winLog::printMessage(const char* level, const char* msg, va_list argList) {

	char* currentTime = createCurrentTime(false);
    logFile = _wfopen(wlogDir, TEXT("a+"));
    if (logFile) {
	    fprintf(logFile, "%s [%s] - ", currentTime, level);
        vfprintf(logFile, msg, argList);
	    fprintf(logFile, "\n");
	    fclose(logFile);
    }
    delete[] currentTime;
}

void winLog::reset(const char* title) {
    const char *t = (title) ? title : FUNAMBOL_HEADER;

    char* currentTime = createCurrentTime(true);
    logFile = _wfopen(wlogDir, TEXT("w+"));
    if (logFile) {
        fprintf(logFile, "%s - # %s\n\n", currentTime, t);
        fclose(logFile);
    }
    delete[] currentTime;
}

size_t winLog::getLogSize() {
    size_t ret = 0;

    logFile = _wfopen(wlogDir, TEXT("r"));
    if (logFile) {
        ret = fgetsize(logFile);
        fclose(logFile);
    }
    return ret;
}

Log *Log::logger;

Log &Log::instance() {
    if (!logger) {
        logger = new winLog();
    }
    return *logger;
}
<commit_msg>removed char[] in log.cpp, using StringBuffer<commit_after>/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2003 - 2007 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#include "base/winlog.h"
#include "base/util/utils.h"
#include "base/util/StringBuffer.h"
#include "base/util/WString.h"

#ifdef _WIN32_WCE
#define FUNAMBOL_HEADER "Funambol Windows Mobile Plug-in Log"
#elif WIN32
#define FUNAMBOL_HEADER "Funambol Win32 Plug-in Log"
#endif

static FILE* logFile = NULL;

static WString      wlogDir(TEXT("\\"));
static StringBuffer logName(LOG_NAME);
static StringBuffer logPath("\\");

winLog::winLog(bool resetLog, const char* path, const char* name) {

    setLogPath(path);
    setLogName(name);

    // MUST use a wchar_t* logDir to manage correctly international chars.
    // If using char* logDir and UTF-8, fopen() is not working correctly and
    // will fail to open the log file. (with UTF-8... why?)
    // So we use _wfopen() and a wchar_t* logDir.
    StringBuffer logDir;
    logDir.sprintf("%s\\%s", logPath.c_str(), logName.c_str());
    WCHAR* tmp = toWideChar(logDir.c_str());
    wlogDir = tmp;
    delete [] tmp;

    //
    // Test to ensure the log file is writable (only if path is set)
    //
    if (path) {
        logFile = _wfopen(wlogDir.c_str(), TEXT("a+"));
        if (logFile == NULL) {
            WCHAR tmp[512];
            wsprintf(tmp, TEXT("Unable to write log file: \"%s\".\nPlease check your user's permissions."), wlogDir.c_str());
            MessageBox(NULL, tmp, TEXT("Funambol"), MB_SETFOREGROUND | MB_OK);
        }
        else {
            fclose(logFile);

            if (resetLog) {
                reset(FUNAMBOL_HEADER);
            }
        }
    }
}

winLog::~winLog() {
    if (logFile != NULL) {
        fclose(logFile);
    }
}

void winLog::setLogPath(const char* configLogPath) {

    if (configLogPath != NULL) {
        logPath = configLogPath;
    } else {
        logPath = ".";
    }
    if (logName.length() > 0){
        StringBuffer logDir;
        logDir.sprintf("%s\\%s", logPath.c_str(), logName.c_str());
        WCHAR* tmp = toWideChar(logDir.c_str());
        wlogDir = tmp;
        delete [] tmp;
    }
}

void winLog::setLogName(const char* configLogName) {

    if (configLogName != NULL) {
        logName = configLogName;
    }
    else {
        logName = LOG_NAME;
    }
    if (logPath){
        StringBuffer logDir;
        logDir.sprintf("%s\\%s", logPath.c_str(), logName.c_str());
        WCHAR* tmp = toWideChar(logDir.c_str());
        wlogDir = tmp;
        delete [] tmp;
    }
}

/*
* return a the time to write into log file. If complete is true, it return
* the date too, else only hours, minutes, seconds and milliseconds
*/
static StringBuffer createCurrentTime(bool complete) {

    SYSTEMTIME sys_time;
    TIME_ZONE_INFORMATION timezone;
    GetLocalTime(&sys_time);
    GetTimeZoneInformation(&timezone);

    StringBuffer ret;

    // calculate offset from UTC/GMT in hours:min, positive value
    // means east of Greenwich (e.g. CET = GMT +1)
    char direction = timezone.Bias <= 0 ? '+' : '-';
    int hours      = abs(timezone.Bias / 60) ;
    int minutes    = abs(timezone.Bias % 60);

    if (complete) {
        char fmtComplete[] = "%04d-%02d-%02d %02d:%02d:%02d GMT %c%d:%02d";
        ret.sprintf(fmtComplete, sys_time.wYear, sys_time.wMonth, sys_time.wDay,
                    sys_time.wHour, sys_time.wMinute, sys_time.wSecond,
                    direction, hours, minutes);
    }
    else {
        char fmt[] = "%02d:%02d:%02d GMT %c%d:%02d";
        ret.sprintf(fmt, sys_time.wHour, sys_time.wMinute, sys_time.wSecond,
                    direction, hours, minutes);
    }
    return ret;
}

void winLog::error(const char*  msg, ...) {
    va_list argList;
    va_start (argList, msg);
    printMessage(LOG_ERROR, msg, argList);
    va_end(argList);
}

void winLog::info(const char*  msg, ...) {
    if (isLoggable(LOG_LEVEL_INFO)) {
        va_list argList;
	    va_start (argList, msg);
        printMessage(LOG_INFO, msg, argList);
	    va_end(argList);
    }
}

void winLog::debug(const char*  msg, ...) {
    if (isLoggable(LOG_LEVEL_DEBUG)) {
	    va_list argList;
        va_start (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        va_end(argList);
    }
}

void winLog::developer(const char*  msg, ...) {
    if (isLoggable(LOG_LEVEL_INFO)) {
        va_list argList;
        va_start (argList, msg);
        printMessage(LOG_DEBUG, msg, argList);
        va_end(argList);
    }
}

void winLog::printMessage(const char* level, const char* msg, va_list argList) {

	StringBuffer currentTime = createCurrentTime(false);
    logFile = _wfopen(wlogDir.c_str(), TEXT("a+"));
    if (logFile) {
        fprintf(logFile, "%s [%s] - ", currentTime.c_str(), level);
        vfprintf(logFile, msg, argList);
	    fprintf(logFile, "\n");
	    fclose(logFile);
    }
}

void winLog::reset(const char* title) {
    const char *t = (title) ? title : FUNAMBOL_HEADER;

    StringBuffer currentTime = createCurrentTime(true);
    logFile = _wfopen(wlogDir.c_str(), TEXT("w+"));
    if (logFile) {
        fprintf(logFile, "%s - # %s\n\n", currentTime.c_str(), t);
        fclose(logFile);
    }
}

size_t winLog::getLogSize() {
    size_t ret = 0;

    logFile = _wfopen(wlogDir.c_str(), TEXT("r"));
    if (logFile) {
        ret = fgetsize(logFile);
        fclose(logFile);
    }
    return ret;
}

Log *Log::logger;

Log &Log::instance() {
    if (!logger) {
        logger = new winLog();
    }
    return *logger;
}
<|endoftext|>


<commit_before><commit_msg>refactoring<commit_after><|endoftext|>


<commit_before>#pragma once

// Mantella
#include <mantella_bits/optimisationAlgorithm/trajectoryBasedAlgorithm.hpp>

namespace mant {
  template <typename ParameterType, class DistanceFunction>
  class HillClimbing : public TrajectoryBasedAlgorithm<ParameterType, DistanceFunction> {
    public:
      explicit HillClimbing(
          const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem) noexcept;

      HillClimbing(const HillClimbing&) = delete;
      HillClimbing& operator=(const HillClimbing&) = delete;

      void setMaximalStepSize(
          const arma::Col<ParameterType>& maximalStepSize);

      std::string to_string() const noexcept override;

    protected:
      arma::Col<ParameterType> maximalStepSize_;

      void optimiseImplementation() noexcept override;

    private:
      void setDefaultMaximalStepSize(std::true_type) noexcept;
      void setDefaultMaximalStepSize(std::false_type) noexcept;
  };

  template <typename ParameterType, class DistanceFunction>
  HillClimbing<ParameterType, DistanceFunction>::HillClimbing(
      const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem) noexcept
    : TrajectoryBasedAlgorithm<ParameterType, DistanceFunction>(optimisationProblem) {
    setDefaultMaximalStepSize(std::is_same<ParameterType, double>());
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::optimiseImplementation() noexcept {
    ++this->numberOfIterations_;

    this->bestParameter_ = this->initialParameter_;
    this->bestSoftConstraintsValue_ = this->optimisationProblem_->getSoftConstraintsValue(this->initialParameter_);
    this->bestObjectiveValue_ = this->optimisationProblem_->getObjectiveValue(this->initialParameter_);

    while(!this->isFinished() && !this->isTerminated()) {
      ++this->numberOfIterations_;

      arma::Col<ParameterType> candidateParameter = this->distanceFunction_.getNeighbour(this->bestParameter_, arma::zeros<arma::Col<double>>(this->optimisationProblem_->getNumberOfDimensions), maximalStepSize_);

      const arma::Col<unsigned int>& belowLowerBound = arma::find(candidateParameter < this->optimisationProblem_->getLowerBounds());
      const arma::Col<unsigned int>& aboveUpperBound = arma::find(candidateParameter > this->optimisationProblem_->getUpperBounds());

      candidateParameter.elem(belowLowerBound) = this->optimisationProblem_->getLowerBounds().elem(belowLowerBound);
      candidateParameter.elem(aboveUpperBound) = this->optimisationProblem_->getUpperBounds().elem(aboveUpperBound);

      const double& candidateSoftConstraintsValue = this->optimisationProblem_->getSoftConstraintsValue(candidateParameter);
      const double& candidateObjectiveValue = this->optimisationProblem_->getObjectiveValue(candidateParameter);

      if(candidateSoftConstraintsValue < this->bestSoftConstraintsValue_ || (candidateSoftConstraintsValue == this->bestSoftConstraintsValue_ && candidateObjectiveValue < this->bestObjectiveValue_)) {
        this->bestParameter_ = candidateParameter;
        this->bestSoftConstraintsValue_ = candidateSoftConstraintsValue;
        this->bestObjectiveValue_ = candidateObjectiveValue;
      }
    }
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::setMaximalStepSize(
      const arma::Col<ParameterType>& maximalStepSize) {
    if(maximalStepSize.n_rows != this->optimisationProblem_->getNumberOfDimensions()) {
      throw std::logic_error("The number of dimensions of the maximal step size (" + std::to_string(maximalStepSize.n_elem) + ") must match the number of dimensions of the optimisation problem (" + std::to_string(this->optimisationProblem_->getNumberOfDimensions()) + ").");
    } else if (arma::any(maximalStepSize <= 0)) {
      throw std::logic_error("The maximal step size must be strict greater than 0.");
    }

    maximalStepSize_ = maximalStepSize;
  }

  template <typename ParameterType, class DistanceFunction>
  std::string HillClimbing<ParameterType, DistanceFunction>::to_string() const noexcept {
    return "HillClimbing";
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::setDefaultMaximalStepSize(
      std::true_type) noexcept {
    setMaximalStepSize(this->distanceFunction_.getDistance(this->optimisationProblem_->getLowerBounds(), this->optimisationProblem_->getUpperBounds()) / 10.0);
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::setDefaultMaximalStepSize(
      std::false_type) noexcept {
    setMaximalStepSize(arma::max(arma::ones<arma::Col<unsigned int>>(this->optimisationProblem_->getNumberOfDimensions()), this->distanceFunction_.getDistance(this->optimisationProblem_->getLowerBounds(), this->optimisationProblem_->getUpperBounds()) / 10.0));
  }
}
<commit_msg>devel: Use more precise is_floating_point<commit_after>#pragma once

// Mantella
#include <mantella_bits/optimisationAlgorithm/trajectoryBasedAlgorithm.hpp>

namespace mant {
  template <typename ParameterType, class DistanceFunction>
  class HillClimbing : public TrajectoryBasedAlgorithm<ParameterType, DistanceFunction> {
    public:
      explicit HillClimbing(
          const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem) noexcept;

      HillClimbing(const HillClimbing&) = delete;
      HillClimbing& operator=(const HillClimbing&) = delete;

      void setMaximalStepSize(
          const arma::Col<ParameterType>& maximalStepSize);

      std::string to_string() const noexcept override;

    protected:
      arma::Col<ParameterType> maximalStepSize_;

      void optimiseImplementation() noexcept override;

    private:
      void setDefaultMaximalStepSize(std::true_type) noexcept;
      void setDefaultMaximalStepSize(std::false_type) noexcept;
  };

  template <typename ParameterType, class DistanceFunction>
  HillClimbing<ParameterType, DistanceFunction>::HillClimbing(
      const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem) noexcept
    : TrajectoryBasedAlgorithm<ParameterType, DistanceFunction>(optimisationProblem) {
    setDefaultMaximalStepSize(std::is_floating_point<ParameterType>());
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::optimiseImplementation() noexcept {
    ++this->numberOfIterations_;

    this->bestParameter_ = this->initialParameter_;
    this->bestSoftConstraintsValue_ = this->optimisationProblem_->getSoftConstraintsValue(this->initialParameter_);
    this->bestObjectiveValue_ = this->optimisationProblem_->getObjectiveValue(this->initialParameter_);

    while(!this->isFinished() && !this->isTerminated()) {
      ++this->numberOfIterations_;

      arma::Col<ParameterType> candidateParameter = this->distanceFunction_.getNeighbour(this->bestParameter_, arma::zeros<arma::Col<double>>(this->optimisationProblem_->getNumberOfDimensions), maximalStepSize_);

      const arma::Col<unsigned int>& belowLowerBound = arma::find(candidateParameter < this->optimisationProblem_->getLowerBounds());
      const arma::Col<unsigned int>& aboveUpperBound = arma::find(candidateParameter > this->optimisationProblem_->getUpperBounds());

      candidateParameter.elem(belowLowerBound) = this->optimisationProblem_->getLowerBounds().elem(belowLowerBound);
      candidateParameter.elem(aboveUpperBound) = this->optimisationProblem_->getUpperBounds().elem(aboveUpperBound);

      const double& candidateSoftConstraintsValue = this->optimisationProblem_->getSoftConstraintsValue(candidateParameter);
      const double& candidateObjectiveValue = this->optimisationProblem_->getObjectiveValue(candidateParameter);

      if(candidateSoftConstraintsValue < this->bestSoftConstraintsValue_ || (candidateSoftConstraintsValue == this->bestSoftConstraintsValue_ && candidateObjectiveValue < this->bestObjectiveValue_)) {
        this->bestParameter_ = candidateParameter;
        this->bestSoftConstraintsValue_ = candidateSoftConstraintsValue;
        this->bestObjectiveValue_ = candidateObjectiveValue;
      }
    }
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::setMaximalStepSize(
      const arma::Col<ParameterType>& maximalStepSize) {
    if(maximalStepSize.n_rows != this->optimisationProblem_->getNumberOfDimensions()) {
      throw std::logic_error("The number of dimensions of the maximal step size (" + std::to_string(maximalStepSize.n_elem) + ") must match the number of dimensions of the optimisation problem (" + std::to_string(this->optimisationProblem_->getNumberOfDimensions()) + ").");
    } else if (arma::any(maximalStepSize <= 0)) {
      throw std::logic_error("The maximal step size must be strict greater than 0.");
    }

    maximalStepSize_ = maximalStepSize;
  }

  template <typename ParameterType, class DistanceFunction>
  std::string HillClimbing<ParameterType, DistanceFunction>::to_string() const noexcept {
    return "HillClimbing";
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::setDefaultMaximalStepSize(
      std::true_type) noexcept {
    setMaximalStepSize(this->distanceFunction_.getDistance(this->optimisationProblem_->getLowerBounds(), this->optimisationProblem_->getUpperBounds()) / 10.0);
  }

  template <typename ParameterType, class DistanceFunction>
  void HillClimbing<ParameterType, DistanceFunction>::setDefaultMaximalStepSize(
      std::false_type) noexcept {
    setMaximalStepSize(arma::max(arma::ones<arma::Col<unsigned int>>(this->optimisationProblem_->getNumberOfDimensions()), this->distanceFunction_.getDistance(this->optimisationProblem_->getLowerBounds(), this->optimisationProblem_->getUpperBounds()) / 10.0));
  }
}
<|endoftext|>


<commit_before>// 5.exercise.12.cpp
//
// Implement a little guessing game called (for some obscure reason) "Bulls and
// Cows". The program has a vector of four different integers in the range 0 to
// 9 (e.g., 1234 but not 1122) and it is the user's task to discover those
// numbers by repeated guesses. Say the number to be guessed is 1234 andd the
// user guesses 1359; the response should be "1 bull and 1 cow" because the
// user got one digit (1) right and in the right position (a bull) and one
// digit (3) right but in the wrong position (a cow). The guessing continues
// until the user gets four bulls, that is, has the four digits correct and in
// the correct order.

#include "std_lib_facilities.h"

vector<int> _guess()
// read a number from
{
}

int main()
try
{
    bool guessed = false;
    // Number to guess: 3461
    vector<int> digits = {3, 4, 6 , 1};
    int guess = 0;

    cout << "Welcome to Bulls and Cows.\n"
         << "Try to guess the four digit sequence I'm thinking about.\n"
         << "No digit appears more than once and I will give you clues,\n"
         << "with \"bulls\" being correct digits in the right position\n"
         << "and \"cows\" being correct digits in wrong position.\n"
         << "Let's start! Your guess ...\n? ";

    while (!guessed) {
        while (cin >> guess) {
            // smallest and biggest combination of 4 distinct digits on [0, 9]
            if (guess >= 123 && guess <= 9876) {
            }
            else {
                cout "Not a four digit number! Please try again.\n? ";
            }
        }
        if (cin.eof()) {
            cout << "Bye, bye!\n";
            return 0;
        } else {
            cout "Not a four digit number! Please try again.\n? ";
        }
    }
}
catch (exception& e)
{
    cout << "Error: " << e.what() << '\n';
    return 1;
}
catch (...)
{
    cout << "Unknown exception!\n";
    return 2;
}
<commit_msg>Advancing in exercise 12 from chapter 5<commit_after>// 5.exercise.12.cpp
//
// Implement a little guessing game called (for some obscure reason) "Bulls and
// Cows". The program has a vector of four different integers in the range 0 to
// 9 (e.g., 1234 but not 1122) and it is the user's task to discover those
// numbers by repeated guesses. Say the number to be guessed is 1234 andd the
// user guesses 1359; the response should be "1 bull and 1 cow" because the
// user got one digit (1) right and in the right position (a bull) and one
// digit (3) right but in the wrong position (a cow). The guessing continues
// until the user gets four bulls, that is, has the four digits correct and in
// the correct order.
//
// Comments:
//  String input is our best bet. The user input sould start by 0 (no one tell
//  us this isn't possible) and by reading an int we loose that leading 0 and
//  thus, we cannot determine if the user input has been 0123 (correct) or
//  123 (wrong). Reading char by char, on the other hand, makes it more compicated.

#include "std_lib_facilities.h"

static const string ex_msg_no_four_digit = "Your input is not a four digit number.";
static const string ex_msg_repeated_digits = "You've enetered repeated digits. "
                                             "This way you're never going to guess it.";

bool check_input(const string& input)
// Checks input to be a 4-unique-digit string.
// Pre-conditions:
//  The length of the string must be exactly 4
//  Each character of the string must be an ASCII (or compatible, as ISO or UTF8)
//      value for chars from '0' to '9' (they are consecutive).
//  Each character of the string must be different
try
{
    if (input.length() != 4) throw runtime_error(ex_msg_no_four_digit);

    for (size_t i = 0; i < input.length(); ++i)
        if (input[i] < '0' || input [i] > '9')
            throw runtime_error(ex_msg_no_four_digit);

    for (size_t i = 0; i < input.length(); ++i)
        for (size_t j = i + 1; j < input.length(); ++j)
            if (i != j && input[i] == input[j])
                throw runtime_error(ex_msg_repeated_digits);

    return true;
}
catch (exception& e)
{
    cout << e.what() << '\n';
    return false;
}

int main()
try
{
    bool guessed = false;
    // Number to guess: 3461
    vector<int> digits = {3, 4, 6 , 1};
    string input = "";
    vector<int> guess;

    cout << "Welcome to Bulls and Cows.\n"
         << "Try to guess the four digit sequence I'm thinking about.\n"
         << "No digit appears more than once and I will give you clues,\n"
         << "with \"bulls\" being correct digits in the right position\n"
         << "and \"cows\" being correct digits in wrong position.\n"
         << "Let's start! Your guess ...\n? ";

    while (!guessed) {
        while (cin >> input) {
            if (check_input(input)) {
                //guess = parse_input(input);
                cout << "Correct input!\n";
            }
            else {
                cout << "INCORRECT input!\n";
            }

        }
        if (cin.eof()) {
            cout << "Bye, bye!\n";
            return 0;
        }
    }
}
catch (exception& e)
{
    cout << "Error: " << e.what() << '\n';
    return 1;
}
catch (...)
{
    cout << "Unknown exception!\n";
    return 2;
}
<|endoftext|>


<commit_before>
#ifndef __ERRORS_HPP__
#define __ERRORS_HPP__

#include <errno.h>
#include <stdio.h>
#include <cstdlib>
#include <signal.h>
#include <stdexcept>

/* Error handling
 *
 * There are several ways to report errors in RethinkDB:
 *  fail_due_to_user_error(msg, ...)    fail and report line number/stack trace. Should only be used when the user
 *                                      is at fault (e.g. provided wrong database file name) and it is reasonable to
 *                                      fail instead of handling the problem more gracefully.
 *
 *  The following macros are used only for the cases of programmer error checking. For the time being they are also used
 *  for system error checking (especially the *_err variants).
 *
 *  crash(msg, ...)                 always fails and reports line number and such. Never returns.
 *  crash_or_trap(msg, ...)         same as above, but traps into debugger if it is present instead of terminating.
 *                                  That means that it possibly can return, and one can continue stepping through the code in the debugger.
 *                                  All off the assert/guarantee functions use crash_or_trap.
 *  assert(cond)                    makes sure cond is true and is a no-op in release mode
 *  assert(cond, msg, ...)          ditto, with additional message and possibly some arguments used for formatting
 *  guarantee(cond)                 same as assert(cond), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee(cond, msg, ...)       same as assert(cond, msg, ...), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee_err(cond)             same as guarantee(cond), but also print errno error description
 *  guarantee_err(cond, msg, ...)   same as guarantee(cond, msg, ...), but also print errno error description
*/

#ifdef __linux__
#if defined __i386 || defined __x86_64
#define BREAKPOINT __asm__ volatile ("int3")
#else   /* x86/amd64 */
#define BREAKPOINT raise(SIGTRAP)
#endif  /* x86/amd64 */
 #endif /* __linux__ */

// TODO: Abort probably is not the right thing to do here.
#define fail_due_to_user_error(msg, ...) do {                       \
        report_user_error(msg, ##__VA_ARGS__);                                     \
        abort();                                                    \
    } while (0)

#define crash(msg, ...) do {                                        \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        abort();                                                    \
    } while (0)

#define crash_or_trap(msg, ...) do {                                \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT;                                                 \
    } while (0)

void report_fatal_error(const char*, int, const char*, ...);
void report_user_error(const char*, ...);

#define stringify(x) #x

#define format_assert_message(assert_type, cond) assert_type " failed: [" stringify(cond) "] "
#define guarantee(cond, msg...) do {    \
        if (!(cond)) {                  \
            crash_or_trap(format_assert_message("Guarantee", cond) msg); \
        }                               \
    } while (0)
#define guarantee_err(cond, msg, args...) do {                                  \
        if (!(cond)) {                                                          \
            if (errno == 0) {                                                   \
                crash_or_trap(format_assert_message("Guarantee", cond) msg);     \
            } else {                                                            \
                crash_or_trap(format_assert_message("Guarantee", cond) " (errno %d - %s) " msg, errno, strerror(errno), ##args);  \
            }                                                                   \
        }                                                                       \
    } while (0)

#define unreachable(msg, ...) crash("Unreachable code: " msg, ##__VA_ARGS__)    // can't use crash_or_trap since code needs to depend on its noreturn property
#define not_implemented(msg, ...) crash_or_trap("Not implemented: " msg, ##__VA_ARGS__)

#define UNUSED(x) ((void) x)
#ifdef NDEBUG
#define assert(cond, msg...) ((void)(0))
#else
#define assert(cond, msg...) do {   \
        if (!(cond)) {              \
            crash_or_trap(format_assert_message("Assertion", cond) msg); \
        }                           \
    } while (0)
#endif

#ifndef NDEBUG
void print_backtrace(FILE *out = stderr, bool use_addr2line = true);
char *demangle_cpp_name(const char *mangled_name);
#endif

#endif /* __ERRORS_HPP__ */
<commit_msg>Added assert_err.<commit_after>
#ifndef __ERRORS_HPP__
#define __ERRORS_HPP__

#include <errno.h>
#include <stdio.h>
#include <cstdlib>
#include <signal.h>
#include <stdexcept>

/* Error handling
 *
 * There are several ways to report errors in RethinkDB:
 *  fail_due_to_user_error(msg, ...)    fail and report line number/stack trace. Should only be used when the user
 *                                      is at fault (e.g. provided wrong database file name) and it is reasonable to
 *                                      fail instead of handling the problem more gracefully.
 *
 *  The following macros are used only for the cases of programmer error checking. For the time being they are also used
 *  for system error checking (especially the *_err variants).
 *
 *  crash(msg, ...)                 always fails and reports line number and such. Never returns.
 *  crash_or_trap(msg, ...)         same as above, but traps into debugger if it is present instead of terminating.
 *                                  That means that it possibly can return, and one can continue stepping through the code in the debugger.
 *                                  All off the assert/guarantee functions use crash_or_trap.
 *  assert(cond)                    makes sure cond is true and is a no-op in release mode
 *  assert(cond, msg, ...)          ditto, with additional message and possibly some arguments used for formatting
 *  assert_err(cond)                same as assert(cond), but also print errno error description
 *  assert_err(cond, msg, ...)      same as assert(cond, msg, ...), but also print errno error description
 *  guarantee(cond)                 same as assert(cond), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee(cond, msg, ...)       same as assert(cond, msg, ...), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee_err(cond)             same as guarantee(cond), but also print errno error description
 *  guarantee_err(cond, msg, ...)   same as guarantee(cond, msg, ...), but also print errno error description
*/

#ifdef __linux__
#if defined __i386 || defined __x86_64
#define BREAKPOINT __asm__ volatile ("int3")
#else   /* x86/amd64 */
#define BREAKPOINT raise(SIGTRAP)
#endif  /* x86/amd64 */
 #endif /* __linux__ */

// TODO: Abort probably is not the right thing to do here.
#define fail_due_to_user_error(msg, ...) do {                       \
        report_user_error(msg, ##__VA_ARGS__);                                     \
        abort();                                                    \
    } while (0)

#define crash(msg, ...) do {                                        \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        abort();                                                    \
    } while (0)

#define crash_or_trap(msg, ...) do {                                \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT;                                                 \
    } while (0)

void report_fatal_error(const char*, int, const char*, ...);
void report_user_error(const char*, ...);

#define stringify(x) #x

#define format_assert_message(assert_type, cond) assert_type " failed: [" stringify(cond) "] "
#define guarantee(cond, msg...) do {    \
        if (!(cond)) {                  \
            crash_or_trap(format_assert_message("Guarantee", cond) msg); \
        }                               \
    } while (0)
#define guarantee_err(cond, msg, args...) do {                                  \
        if (!(cond)) {                                                          \
            if (errno == 0) {                                                   \
                crash_or_trap(format_assert_message("Guarantee", cond) msg);    \
            } else {                                                            \
                crash_or_trap(format_assert_message("Guarantee", cond) " (errno %d - %s) " msg, errno, strerror(errno), ##args);  \
            }                                                                   \
        }                                                                       \
    } while (0)

#define unreachable(msg, ...) crash("Unreachable code: " msg, ##__VA_ARGS__)    // can't use crash_or_trap since code needs to depend on its noreturn property
#define not_implemented(msg, ...) crash_or_trap("Not implemented: " msg, ##__VA_ARGS__)

#define UNUSED(x) ((void) x)
#ifdef NDEBUG
#define assert(cond, msg...) ((void)(0))
#define assert_err(cond, msg...) ((void)(0))
#else
#define assert(cond, msg...) do {   \
        if (!(cond)) {              \
            crash_or_trap(format_assert_message("Assertion", cond) msg); \
        }                           \
    } while (0)
#define assert_err(cond, msg, args...) do {                                 \
        if (!(cond)) {                                                      \
            if (errno == 0) {                                               \
                crash_or_trap(format_assert_message("Assert", cond) msg);   \
            } else {                                                        \
                crash_or_trap(format_assert_message("Assert", cond) " (errno %d - %s) " msg, errno, strerror(errno), ##args);  \
            }                                                               \
        }                                                                   \
    } while (0)
#endif

#ifndef NDEBUG
void print_backtrace(FILE *out = stderr, bool use_addr2line = true);
char *demangle_cpp_name(const char *mangled_name);
#endif

#endif /* __ERRORS_HPP__ */
<|endoftext|>