#include "OutputManager.hpp"
#include "ParamResponsePair.hpp"
#include "SimulationResponse.hpp"

#ifdef _WIN32
#include "dakota_windows.h"
#endif

#include <Teuchos_UnitTestHarness.hpp>
#include <boost/filesystem/operations.hpp>
#include <cmath>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

#ifndef M_LOG2E
#define M_LOG2E 1.4426950408889634074
#endif

using namespace Dakota;

/** In-core test with 1 variable/response */
TEUCHOS_UNIT_TEST(io, restart_1var)
{
  // NOTE: A possible problem with a stringstream is it isn't
  // explicitly a binary stream (std::ios::binary)
  std::stringstream rst_stream;

  // Mock up a single variable
  SizetArray vc_totals(NUM_VC_TOTALS);
  vc_totals[0] = 1;
  std::pair<short, short> view(MIXED_ALL, EMPTY_VIEW);
  SharedVariablesData svd(view, vc_totals);
  Variables vars(svd);

  // Mock up a single response
  // active set with 1 var / 1 resp
  ActiveSet as(1, 1);
  // TODO: can't default construct srd...
  SharedResponseData srd(as);
  Response resp(srd);

  String iface_id = "RST_IFACE";

  int num_evals = 10;
  PRPArray prps_out, prps_in;
  // added scope to force destruction of writer/reader and close the file
  {
    RestartWriter rst_writer(rst_stream);

    for (int eval_id = 1; eval_id <= num_evals; ++eval_id) {
      vars.continuous_variable(M_LOG2E + (Real) (eval_id-1), 0);
      resp.function_value(M_PI + (Real) (eval_id-1), 0);
      // TODO: code is not robust to writing empty PRP (seg fault)
      // NOTE: This makes a deep copy of vars/resp by default:
      ParamResponsePair prp_out(vars, iface_id, resp, eval_id);
      prps_out.push_back(prp_out);
      rst_writer.append_prp(prp_out);
    }
  }
  {
    boost::archive::binary_iarchive restart_input_archive(rst_stream);
    for (int eval_id = 1; eval_id <= num_evals; ++eval_id) {
      ParamResponsePair prp_in;
      restart_input_archive & prp_in;
      prps_in.push_back(prp_in);
    }
  }

  TEST_EQUALITY(prps_in, prps_out);

  // std::cout << std::setprecision(20) << std::setw(30) << prp_in << '\n'
  // 	    << std::setprecision(20)  << prp_out << '\n';
}

/** File-based test with multiple variables/responses */
TEUCHOS_UNIT_TEST(io, restart_allvar)
{
  String rst_filename("restart_allvar.rst");
  boost::filesystem::remove(rst_filename);

  // Mock up one of each variable
  SizetArray vc_totals(NUM_VC_TOTALS, 1);
  vc_totals.assign(NUM_VC_TOTALS, 1);
  std::pair<short, short> view(MIXED_ALL, EMPTY_VIEW);
  SharedVariablesData svd(view, vc_totals);
  Variables vars(svd);
  for (size_t i=0; i<vars.acv(); ++i)
    vars.all_continuous_variable(M_LOG2E + (Real) i, i);
  for (size_t i=0; i<vars.adiv(); ++i)
    vars.all_discrete_int_variable(i, i);
  for (size_t i=0; i<vars.adsv(); ++i)
    vars.all_discrete_string_variable(String("sv") +
				      boost::lexical_cast<String>(i), i);
  for (size_t i=0; i<vars.adrv(); ++i)
    vars.all_discrete_real_variable(100.0 + (Real) i, i);

  // active set with 12 var / 2 resp, including gradients, Hessians
  int num_resp = 2;
  ActiveSet as(num_resp, NUM_VC_TOTALS);
  as.request_values(7);
  as.derivative_start_value(0);

  // TODO: can't default construct srd...
  // Also the Response doesn't get the right size...
  // SharedResponseData srd(as);
  // srd.response_type(SIMULATION_RESPONSE);
  //  Response resp(srd);

  // TODO: A number of Response constructors are partial, and may
  // leave the resulting object in a bad state.  Have to use this ctor
  // for it to work.
  Response resp(SIMULATION_RESPONSE, as);

  resp.function_value(M_PI, 0);
  resp.function_value(2*M_PI, 1);

  // This calls srand, but should be limited to this test
  // TODO: utilities to use Boost RNG to populate matrices
  Teuchos::ScalarTraits<Real>::seedrandom(12345);

  RealMatrix gradient(NUM_VC_TOTALS, num_resp);
  gradient.random();
  resp.function_gradients(gradient);

  RealSymMatrix hess0(NUM_VC_TOTALS, NUM_VC_TOTALS);
  hess0.random();
  resp.function_hessian(hess0, 0);

  RealSymMatrix hess1(NUM_VC_TOTALS, NUM_VC_TOTALS);
  hess1.random();
  resp.function_hessian(hess1, 1);

  String iface_id = "RST_IFACE";
  int eval_id = 1;

  // TODO: code is not robust to writing empty PRP (seg fault)
  int num_evals = 10;
  PRPArray prps_out, prps_in;
  // added scope to force destruction of writer/reader and close the file
  {
    RestartWriter rst_writer(rst_filename);

    for (int eval_id = 1; eval_id <= num_evals; ++eval_id) {
      // For now this just make a small tweak so variables/resp are unique
      vars.continuous_variable(M_LOG2E + (Real) (eval_id-1), 0);
      resp.function_value(M_PI + (Real) (eval_id-1), 0);
      // NOTE: This makes a deep copy of vars/resp by default:
      ParamResponsePair prp_out(vars, iface_id, resp, eval_id);
      prps_out.push_back(prp_out);
      rst_writer.append_prp(prp_out);
    }

  }
  {
    std::ifstream restart_input_fs(rst_filename.c_str(), std::ios::binary);
    boost::archive::binary_iarchive restart_input_archive(restart_input_fs);
    for (int eval_id = 1; eval_id <= num_evals; ++eval_id) {
      ParamResponsePair prp_in;
      restart_input_archive & prp_in;
      prps_in.push_back(prp_in);
    }
  }

  TEST_EQUALITY(prps_in, prps_out);

  // std::cout << std::setprecision(20) << std::setw(30) << prp_in << '\n'
  // 	    << std::setprecision(20)  << prp_out << '\n';

  boost::filesystem::remove(rst_filename);
}


/*
 *  Copyright 2011-2013 Maxim Milakov
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "local_contrast_subtractive_layer_testing_schema.h"

#include "../neural_network_exception.h"
#include "../local_contrast_subtractive_layer.h"
#include "../nn_types.h"

#include "local_contrast_subtractive_2d_layer_tester_cuda.h"

#include <boost/format.hpp>

namespace nnforge
{
	namespace cuda
	{
		local_contrast_subtractive_layer_testing_schema::local_contrast_subtractive_layer_testing_schema()
		{
		}

		local_contrast_subtractive_layer_testing_schema::~local_contrast_subtractive_layer_testing_schema()
		{
		}

		const boost::uuids::uuid& local_contrast_subtractive_layer_testing_schema::get_uuid() const
		{
			return local_contrast_subtractive_layer::layer_guid;
		}

		layer_testing_schema_smart_ptr local_contrast_subtractive_layer_testing_schema::create_specific() const
		{
			return layer_testing_schema_smart_ptr(new local_contrast_subtractive_layer_testing_schema());
		}

		layer_tester_cuda_smart_ptr local_contrast_subtractive_layer_testing_schema::create_tester_specific(
			const layer_configuration_specific& input_configuration_specific,
			const layer_configuration_specific& output_configuration_specific) const
		{
			layer_tester_cuda_smart_ptr res;

			switch (output_configuration_specific.dimension_sizes.size())
			{
			case 2:
				res = layer_tester_cuda_smart_ptr(new local_contrast_subtractive_2d_layer_tester_cuda());
				break;
			default:
				throw neural_network_exception((boost::format("No CUDA tester for the local contrast subtractive layer of %1% dimensions") % output_configuration_specific.dimension_sizes.size()).str());
				break;
			}

			return res;
		}

		std::vector<const_cuda_linear_buffer_device_smart_ptr> local_contrast_subtractive_layer_testing_schema::get_schema_buffers() const
		{
			std::vector<const_cuda_linear_buffer_device_smart_ptr> res;

			nnforge_shared_ptr<const local_contrast_subtractive_layer> layer_derived = nnforge_dynamic_pointer_cast<const local_contrast_subtractive_layer>(layer_schema);

			res.push_back(
				cuda_linear_buffer_device_smart_ptr(new cuda_linear_buffer_device(
					&(*layer_derived->feature_maps_affected.begin()),
					layer_derived->feature_maps_affected.size() * sizeof(unsigned int)))
				);

			for(std::vector<std::vector<float> >::const_iterator it = layer_derived->window_weights_list.begin(); it != layer_derived->window_weights_list.end(); ++it)
			{
				const std::vector<float>& current_weights = *it;
				res.push_back(
					cuda_linear_buffer_device_smart_ptr(new cuda_linear_buffer_device(
						&(*current_weights.begin()),
						current_weights.size() * sizeof(float)))
					);
			}

			return res;
		}
	}
}


/*******
edit_distance: STL and Boost compatible edit distance functions for C++

Copyright (c) 2013 Erik Erlandson

Author:  Erik Erlandson <erikerlandson@yahoo.com>

Distributed under the Boost Software License, Version 1.0.
See accompanying file LICENSE or copy at
http://www.boost.org/LICENSE_1_0.txt
*******/

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using std::string;
using std::vector;
using std::cerr;
using std::cout;
using std::endl;

#include <boost/algorithm/sequence/edit_distance.hpp>
using boost::algorithm::sequence::edit_distance;
using namespace boost::algorithm::sequence::parameter;

void load_file_lines(char const* fname, vector<string>& lines) {
    std::ifstream f;
    f.open(fname, std::ifstream::in);
    if (!f.good()) {
        cerr << "error loading " << fname << endl;
        exit(1);
    }

    lines.clear();
    lines.reserve(10000);
    while (!f.eof()) {
        lines.push_back(string());
        std::getline(f, lines.back());
    }
}

struct diff_handler {
    struct hunk {
        hunk() : del(), ins(), del_pos(0), ins_pos(0) {}
        size_t del_pos;
        size_t ins_pos;
        vector<string> del;
        vector<string> ins;
    };

    vector<hunk> hunks;
    size_t src_pos;
    size_t dst_pos;
    bool needhunk;

    diff_handler() : hunks(), src_pos(0), dst_pos(0), needhunk(true) {}

    inline void newhunk() {
        hunks.push_back(hunk());
        hunks.back().del_pos = src_pos;
        hunks.back().ins_pos = dst_pos;
        needhunk = false;
    }

    inline void insertion(const string& s, size_t) {
        if (needhunk) newhunk();
        hunks.back().ins.push_back(s);
        ++dst_pos;
    }

    inline void deletion(const string& s, size_t) {
        if (needhunk) newhunk();
        hunks.back().del.push_back(s);
        ++src_pos;
    }

    inline void equality(const string&, const string&) {
        needhunk = true;
        ++src_pos;
        ++dst_pos;
    }

    void write_standard_format(std::ostream& ostrm) {
        for (vector<hunk>::iterator h(hunks.begin());  h != hunks.end();  ++h) {

            if (h->del.empty())  ostrm << h->del_pos;
            else {
                ostrm << h->del_pos + 1;
                if (h->del.size() > 1)  ostrm << "," << h->del_pos + h->del.size();
            }

            ostrm << ((h->del.empty()) ? "a" : ((h->ins.empty()) ? "d" : "c"));

            if (h->ins.empty())  ostrm << h->ins_pos;
            else {
                ostrm << h->ins_pos + 1;
                if (h->ins.size() > 1)  ostrm << "," << h->ins_pos + h->ins.size();
            }

            ostrm << endl;

            for (vector<string>::iterator s(h->del.begin()); s != h->del.end();  ++s)
                ostrm << "< " << *s << endl;

            if (!h->del.empty()  &&  !h->ins.empty())  ostrm << "---" << endl;

            for (vector<string>::iterator s(h->ins.begin()); s != h->ins.end();  ++s)
                ostrm << "> " << *s << endl;
        }
    }
};

int main(int argc, char** argv) {
    if (argc != 3) {
        cerr << "usage: " << argv[0] << " <src> <dst>" << endl;
        exit(1);
    }

    vector<string> src;
    vector<string> dst;

    load_file_lines(argv[1], src);
    load_file_lines(argv[2], dst);

    diff_handler handler;

    const size_t term_cost = 10000;
    int err=0;

    size_t dist = edit_distance(src, dst, _script=handler, _max_cost=term_cost);
    if (dist >= term_cost) {
        cerr << "WARNING: file difference exceeded " << term_cost << " lines, reported difference is not minimal!" << endl;
        err = 1;
    }

    handler.write_standard_format(cout);

    return err;
}


//
// Created by kellerberrin on 16/12/17.
//

#include <boost/numeric/ublas/triangular.hpp>

#include "kel_exec_env.h"
#include "kgl_statistics_upgma.h"

namespace kgl = kellerberrin::genome;
namespace bnu = boost::numeric::ublas;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Implementation of a strict lower triangular distance matrix using the Boost library.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

using DistanceMatrixImplType = bnu::triangular_matrix<kgl::DistanceType_t, bnu::strict_lower>;

class kgl::DistanceMatrix::BoostDistanceMatrix {

public:

  explicit BoostDistanceMatrix(size_t matrix_size) : lower_triangular_(matrix_size, matrix_size) {}
  explicit BoostDistanceMatrix(const BoostDistanceMatrix&) = default;
  ~BoostDistanceMatrix() = default;

  size_t size() const { return lower_triangular_.size1(); }
  void resize(size_t new_size) { lower_triangular_.resize(new_size, new_size, false); }
  kgl::DistanceType_t getDistance(size_t i, size_t j) const;
  void setDistance(size_t i, size_t j, kgl::DistanceType_t distance);

private:

  DistanceMatrixImplType lower_triangular_;

};

kgl::DistanceType_t kgl::DistanceMatrix::BoostDistanceMatrix::getDistance(size_t i, size_t j) const {

  if (i >= size() or i >= size()) {

    ExecEnv::log().error("Index too large i: {}, j:{} for distance matrix size: {}", i, j, size());
    return 0;

  }

  if (i == j) {

    return 0;

  }

  if (j > i) {

    std::swap(i, j);

  }

  return lower_triangular_(i,j);

}

void kgl::DistanceMatrix::BoostDistanceMatrix::setDistance(size_t i, size_t j, kgl::DistanceType_t distance) {

  if (i >= size() or i >= size()) {

    ExecEnv::log().error("Index too large i: {}, j:{} for distance matrix size: {}", i, j, size());
    return;

  }

  if (i == j) {

    return;

  }

  if (j > i) {

    std::swap(i, j);

  }

  lower_triangular_(i,j) = distance;

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Public class of the UPGMA distance matrix.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

kgl::DistanceMatrix::DistanceMatrix() : diagonal_impl_ptr_(std::make_unique<kgl::DistanceMatrix::BoostDistanceMatrix>(1)) {}

kgl::DistanceMatrix::DistanceMatrix(size_t matrix_size) : diagonal_impl_ptr_(std::make_unique<kgl::DistanceMatrix::BoostDistanceMatrix>(matrix_size)) {}

kgl::DistanceMatrix::DistanceMatrix(const DistanceMatrix& copy) : diagonal_impl_ptr_(std::make_unique<kgl::DistanceMatrix::BoostDistanceMatrix>(*copy.diagonal_impl_ptr_)) {}

kgl::DistanceMatrix::~DistanceMatrix() {}  // DO NOT DELETE or USE DEFAULT. Required because of incomplete PIMPL type.

size_t kgl::DistanceMatrix::size() const {

  return diagonal_impl_ptr_->size();

}

void kgl::DistanceMatrix::resize(size_t new_size) {

  diagonal_impl_ptr_->resize(new_size);

}

kgl::DistanceType_t kgl::DistanceMatrix::getDistance(size_t i, size_t j) const {

  return diagonal_impl_ptr_->getDistance( i, j);

}

void kgl::DistanceMatrix::setDistance(size_t i, size_t j, DistanceType_t value) {

  diagonal_impl_ptr_->setDistance( i, j, value);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Distance Implementation functions.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

kgl::DistanceType_t kgl::DistanceMatrix::minimum(size_t& i, size_t& j) const {

  bool first_pass = true;
  kgl::DistanceType_t min_distance = 0;
  for (size_t row = 0; row < size(); ++row) {

    for (size_t column = 0; column < row; ++column) {

      if (first_pass) {

        min_distance = getDistance( row, column);
        i = row;
        j = column;
        first_pass = false;

      } else {

        kgl::DistanceType_t check_min = getDistance( row, column);
        if (check_min < min_distance) {

          min_distance = check_min;
          i = row;
          j = column;

        }

      }

    }

  }

  return min_distance;

}

kgl::DistanceType_t kgl::DistanceMatrix::maximum(size_t& i, size_t& j) const {

  bool first_pass = true;
  kgl::DistanceType_t max_distance = 0;
  for (size_t row = 0; row < size(); ++row) {

    for (size_t column = 0; column < row; ++column) {

      if (first_pass) {

        max_distance = getDistance( row, column);
        i = row;
        j = column;
        first_pass = false;

      } else {

        kgl::DistanceType_t check_max = getDistance( row, column);
        if (check_max > max_distance) {

          max_distance = check_max;
          i = row;
          j = column;

        }

      }

    }

  }

  return max_distance;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// UPGMA Distance matrix
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

size_t kgl::UPGMAMatrix::getLeafCount(size_t leaf_idx) const {

  if (leaf_idx >= node_vector_ptr_->size()) {

    ExecEnv::log().error("getLeafCount(), bad index: {}, node vector size: {}", leaf_idx, node_vector_ptr_->size());
    return 1;
  }

  return node_vector_ptr_->at(leaf_idx)->leafNodeCount();

}

kgl::DistanceType_t kgl::UPGMAMatrix::distance(std::shared_ptr<PhyloNode> row_node,
                                     std::shared_ptr<PhyloNode> column_node) const {

  return row_node->node()->distance(column_node->node());

}

void kgl::UPGMAMatrix::initializeDistance() {

  for (size_t row = 0; row < node_vector_ptr_->size(); ++row) {

    for (size_t column = 0; column < row; column++) {

      distance_matrix_.setDistance(row, column, distance(node_vector_ptr_->at(row), node_vector_ptr_->at(column)));

    }

  }

  normalizeDistance();

}

void kgl::UPGMAMatrix::normalizeDistance() {

  rescaleDistance();
  identityZeroDistance();

}

void kgl::UPGMAMatrix::identityZeroDistance() {

  for (size_t row = 0; row < node_vector_ptr_->size(); ++row) {

    for (size_t column = 0; column < row; column++) {

      if (node_vector_ptr_->at(row)->node()->zeroDistance(node_vector_ptr_->at(column)->node())) {

        distance_matrix_.setDistance(row, column, 0.0);

      }

    }

  }

}

void kgl::UPGMAMatrix::rescaleDistance() {

  size_t row;
  size_t column;
  DistanceType_t min = distance_matrix_.minimum(row, column);
  DistanceType_t max = distance_matrix_.maximum(row, column);
  DistanceType_t range = max - min;

  if (range == 0.0) {

    ExecEnv::log().error("UPGMAMatrix::normalizeDistance() distance range for all nodes is zero");
    return;

  }

  for (size_t row = 0; row < node_vector_ptr_->size(); ++row) {

    for (size_t column = 0; column < row; column++) {

      DistanceType_t raw_distance = distance_matrix_.getDistance(row, column);
      DistanceType_t adj_distance = (raw_distance - min) / range;
      distance_matrix_.setDistance(row, column, adj_distance);

    }

  }

}

// Reduces the distance matrix.
// The reduced column is the left most column (column, j index = 0)
void kgl::UPGMAMatrix::reduceDistance(size_t i, size_t j) {

  // Save and resize
  DistanceMatrix temp_distance(distance_matrix_);

  size_t reduce_size = distance_matrix_.size() - 1;

  distance_matrix_.resize(reduce_size);

  // re-populate merged distances.
  size_t idx_row = 1;
  for(size_t row = 0; row < temp_distance.size(); ++row) {

    if (row != i and row != j) {

      kgl::DistanceType_t i_leaf = getLeafCount(i);
      kgl::DistanceType_t j_leaf = getLeafCount(j);
      kgl::DistanceType_t calc_dist = (i_leaf * temp_distance.getDistance(row, i)) + (j_leaf * temp_distance.getDistance(row, j));
      calc_dist = calc_dist / (i_leaf + j_leaf);
      distance_matrix_.setDistance(idx_row, 0, calc_dist);
      ++idx_row;

    }

  }

  // re-populate other distances.
  if (distance_matrix_.size() <= 2) {

    return;

  }

  idx_row = 2;  // shift down 2 rows.
  bool update = false;
  for (size_t row = 0; row < temp_distance.size(); ++row) {

    if (row != i and row != j) {

      size_t idx_column = 1;  // shift to column = 1
      for (size_t column = 0; column < row; ++column) {

        if (column != i and column != j) {

          distance_matrix_.setDistance(idx_row, idx_column, temp_distance.getDistance(row, column));
          idx_column++;
          update = true;

        }

      }

      if (update) {

        idx_row++;
        update = false;

      }

    }

  }

}

bool kgl::UPGMAMatrix::reduceNode(size_t row, size_t column, DistanceType_t minimum) {

  std::shared_ptr<PhyloNodeVector> temp_node_vector_ptr(std::make_shared<PhyloNodeVector>());
  std::shared_ptr<PhyloNode> column_node = nullptr;
  std::shared_ptr<PhyloNode> row_node = nullptr;

  for (size_t idx = 0; idx < node_vector_ptr_->size(); idx++) {

    if (not (idx == column or idx == row)) {

      temp_node_vector_ptr->push_back(node_vector_ptr_->at(idx));

    } else if (idx == column) {

      column_node = node_vector_ptr_->at(idx);

    } else if (idx == row) {

      row_node = node_vector_ptr_->at(idx);

    }

  }

  if (not column_node or not row_node) {

    ExecEnv::log().error("Null pointer found, error calculating UPGMA, row: {}, column: {}, nodes: {}",
                         row, column, node_vector_ptr_->size());
    return false;

  }

  node_vector_ptr_ = temp_node_vector_ptr;

  DistanceType_t node_distance = minimum / 2;
  DistanceType_t row_distance = node_distance - row_node->distance();
  row_node->distance(row_distance);
  DistanceType_t column_distance = node_distance - column_node->distance();
  column_node->distance(column_distance);
  std::shared_ptr<PhyloNode> merged_node(std::make_shared<PhyloNode>(row_node->node()));
  merged_node->distance(node_distance);
  merged_node->addOutNode(row_node);
  merged_node->addOutNode(column_node);
  // Insert the merged node at the front of the vector.
  // This matches the pattern of the reduction of the distance matrix (above).
  node_vector_ptr_->insert(node_vector_ptr_->begin(), merged_node);

  return true;

}

void kgl::UPGMAMatrix::UPGMATree() {

  while (node_vector_ptr_->size() > 1) {

    size_t row = 0;
    size_t column = 0;
    DistanceType_t min = distance_matrix_.minimum(row, column);

    reduceDistance(row, column);

    reduceNode(row, column, min);

  } // while reduceNode.

}

bool kgl::UPGMAMatrix::writeNewick(const std::string& file_name) const {

  std::ofstream newick_file;

  // Open input file.

  newick_file.open(file_name);

  if (not newick_file.good()) {

    ExecEnv::log().error("I/O error; could not open Newick file: {}", file_name);
    return false;

  }

  for (const auto& node : *node_vector_ptr_) {

    writeNode(node, newick_file);

  }

  newick_file << ";";

  newick_file.close();

  return true;

}

void kgl::UPGMAMatrix::writeNode(const std::shared_ptr<PhyloNode>& node, std::ofstream& newick_file) const {

  if (node->outNodes().size() > 0) {

    newick_file << "(";

    bool first_pass = true;
    for (const auto& child_node : node->outNodes()) {

      if (first_pass) {

        first_pass = false;

      } else {

        newick_file << ",";

      }

      writeNode(child_node.second, newick_file);

    }

    newick_file << ")";

  } else {

    node->node()->writeNode(newick_file);

  }

  newick_file << ":";
  newick_file << node->distance();

}


//==================================================================================================
/*!

  Copyright 2015 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#include <boost/simd/function/scalar/bitget.hpp>
#include <simd_test.hpp>
#include <boost/dispatch/meta/as_integer.hpp>
#include <boost/simd/constant/inf.hpp>
#include <boost/simd/constant/minf.hpp>
#include <boost/simd/constant/mone.hpp>
#include <boost/simd/constant/nan.hpp>
#include <boost/simd/constant/one.hpp>
#include <boost/simd/constant/zero.hpp>

STF_CASE_TPL (" bitget uit",  STF_UNSIGNED_INTEGRAL_TYPES)
{
  namespace bs = boost::simd;

  using bs::bitget;
  using iT =  boost::dispatch::as_integer_t<T, unsigned>;

  // return type conformity test
  STF_EXPR_IS( bitget(T(), iT()), iT );

  // specific values tests
  STF_EQUAL(bitget(T(3),1), bs::One<iT>());
  STF_EQUAL(bitget(T(3),2), bs::One<iT>());
  STF_EQUAL(bitget(T(3),3), bs::Zero<iT>());
} // end of test for unsigned_int_

STF_CASE_TPL (" bitget si",  STF_SIGNED_INTEGRAL_TYPES)
{
  namespace bs = boost::simd;

  using bs::bitget;
  using iT =  boost::dispatch::as_integer_t<T, unsigned>;

  // return type conformity test
  STF_EXPR_IS( bitget(T(), iT()), iT );

  // specific values tests
  STF_EQUAL(bitget(T(2),1), bs::Zero<iT>());
  STF_EQUAL(bitget(T(2),2), bs::One<iT>());
  STF_EQUAL(bitget(T(-1), sizeof(T)*CHAR_BIT), bs::One<iT>());
} // end of test for unsigned_int_


// Copyright (C) 2015 Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.

#include <dlib/python.h>
#include <dlib/geometry.h>
#include <pybind11/stl_bind.h>
#include "indexing.h"
#include "opaque_types.h"
#include <dlib/filtering.h>

using namespace dlib;
using namespace std;

namespace py = pybind11;

// ----------------------------------------------------------------------------------------

long left(const rectangle& r) { return r.left(); }
long top(const rectangle& r) { return r.top(); }
long right(const rectangle& r) { return r.right(); }
long bottom(const rectangle& r) { return r.bottom(); }
long width(const rectangle& r) { return r.width(); }
long height(const rectangle& r) { return r.height(); }
unsigned long area(const rectangle& r) { return r.area(); }

double dleft(const drectangle& r) { return r.left(); }
double dtop(const drectangle& r) { return r.top(); }
double dright(const drectangle& r) { return r.right(); }
double dbottom(const drectangle& r) { return r.bottom(); }
double dwidth(const drectangle& r) { return r.width(); }
double dheight(const drectangle& r) { return r.height(); }
double darea(const drectangle& r) { return r.area(); }

template <typename rect_type>
bool is_empty(const rect_type& r) { return r.is_empty(); }

template <typename rect_type>
point center(const rect_type& r) { return center(r); }

template <typename rect_type>
point dcenter(const rect_type& r) { return dcenter(r); }

template <typename rect_type, typename ptype>
bool contains(const rect_type& r, const ptype& p) { return r.contains(p); }

template <typename rect_type>
bool contains_xy(const rect_type& r, const long x, const long y) { return r.contains(point(x, y)); }

template <typename rect_type>
bool contains_rec(const rect_type& r, const rect_type& r2) { return r.contains(r2); }

template <typename rect_type>
rect_type intersect(const rect_type& r, const rect_type& r2) { return r.intersect(r2); }

template <typename rect_type>
string print_rectangle_str(const rect_type& r)
{
    std::ostringstream sout;
    sout << r;
    return sout.str();
}

string print_rectangle_repr(const rectangle& r)
{
    std::ostringstream sout;
    sout << "rectangle(" << r.left() << "," << r.top() << "," << r.right() << "," << r.bottom() << ")";
    return sout.str();
}

string print_drectangle_repr(const drectangle& r)
{
    std::ostringstream sout;
    sout << "drectangle(" << r.left() << "," << r.top() << "," << r.right() << "," << r.bottom() << ")";
    return sout.str();
}

string print_rect_filter(const rect_filter& r)
{
    std::ostringstream sout;
    sout << "rect_filter(";
    sout << "measurement_noise="<<r.get_left().get_measurement_noise();
    sout << ", typical_acceleration="<<r.get_left().get_typical_acceleration();
    sout << ", max_measurement_deviation="<<r.get_left().get_max_measurement_deviation();
    sout << ")";
    return sout.str();
}

// ----------------------------------------------------------------------------------------

void bind_rectangles(py::module& m)
{
    {
    typedef rectangle type;
    py::class_<type>(m, "rectangle", "This object represents a rectangular area of an image.")
        .def(py::init<long,long,long,long>(), py::arg("left"),py::arg("top"),py::arg("right"),py::arg("bottom"))
        .def(py::init<drectangle>(), py::arg("rect"))
        .def(py::init<rectangle>(), py::arg("rect"))
        .def(py::init())
        .def("area",   &::area)
        .def("left",   &::left)
        .def("top",    &::top)
        .def("right",  &::right)
        .def("bottom", &::bottom)
        .def("width",  &::width)
        .def("height", &::height)
        .def("tl_corner", &type::tl_corner, "Returns the top left corner of the rectangle.")
        .def("tr_corner", &type::tr_corner, "Returns the top right corner of the rectangle.")
        .def("bl_corner", &type::bl_corner, "Returns the bottom left corner of the rectangle.")
        .def("br_corner", &type::br_corner, "Returns the bottom right corner of the rectangle.")
        .def("is_empty", &::is_empty<type>)
        .def("center", &::center<type>)
        .def("dcenter", &::dcenter<type>)
        .def("contains", &::contains<type,point>, py::arg("point"))
        .def("contains", &::contains<type,dpoint>, py::arg("point"))
        .def("contains", &::contains_xy<type>, py::arg("x"), py::arg("y"))
        .def("contains", &::contains_rec<type>, py::arg("rectangle"))
        .def("intersect", &::intersect<type>, py::arg("rectangle"))
        .def("__str__", &::print_rectangle_str<type>)
        .def("__repr__", &::print_rectangle_repr)
        .def(py::self += point())
        .def(py::self + point())
        .def(py::self += rectangle())
        .def(py::self + rectangle())
        .def(py::self == py::self)
        .def(py::self != py::self)
        .def(py::pickle(&getstate<type>, &setstate<type>));
    }
    {
    typedef drectangle type;
    py::class_<type>(m, "drectangle", "This object represents a rectangular area of an image with floating point coordinates.")
        .def(py::init<double,double,double,double>(), py::arg("left"), py::arg("top"), py::arg("right"), py::arg("bottom"))
        .def(py::init<rectangle>(), py::arg("rect"))
        .def(py::init<drectangle>(), py::arg("rect"))
        .def(py::init<>())
        .def("area",   &::darea)
        .def("left",   &::dleft)
        .def("top",    &::dtop)
        .def("right",  &::dright)
        .def("bottom", &::dbottom)
        .def("width",  &::dwidth)
        .def("height", &::dheight)
        .def("is_empty", &::is_empty<type>)
        .def("center", &::center<type>)
        .def("dcenter", &::dcenter<type>)
        .def("tl_corner", &type::tl_corner, "Returns the top left corner of the rectangle.")
        .def("tr_corner", &type::tr_corner, "Returns the top right corner of the rectangle.")
        .def("bl_corner", &type::bl_corner, "Returns the bottom left corner of the rectangle.")
        .def("br_corner", &type::br_corner, "Returns the bottom right corner of the rectangle.")
        .def("contains", &::contains<type,point>, py::arg("point"))
        .def("contains", &::contains<type,dpoint>, py::arg("point"))
        .def("contains", &::contains_xy<type>, py::arg("x"), py::arg("y"))
        .def("contains", &::contains_rec<type>, py::arg("rectangle"))
        .def("intersect", &::intersect<type>, py::arg("rectangle"))
        .def("__str__", &::print_rectangle_str<type>)
        .def("__repr__", &::print_drectangle_repr)
        .def(py::self == py::self)
        .def(py::self != py::self)
        .def(py::pickle(&getstate<type>, &setstate<type>));
    }

    {
        typedef rect_filter type;
        py::class_<type>(m, "rect_filter",
            R"asdf(
                This object is a simple tool for filtering a rectangle that
                measures the location of a moving object that has some non-trivial
                momentum.  Importantly, the measurements are noisy and the object can
                experience sudden unpredictable accelerations.  To accomplish this
                filtering we use a simple Kalman filter with a state transition model of:

                    position_{i+1} = position_{i} + velocity_{i}
                    velocity_{i+1} = velocity_{i} + some_unpredictable_acceleration

                and a measurement model of:

                    measured_position_{i} = position_{i} + measurement_noise

                Where some_unpredictable_acceleration and measurement_noise are 0 mean Gaussian
                noise sources with standard deviations of typical_acceleration and
                measurement_noise respectively.

                To allow for really sudden and large but infrequent accelerations, at each
                step we check if the current measured position deviates from the predicted
                filtered position by more than max_measurement_deviation*measurement_noise
                and if so we adjust the filter's state to keep it within these bounds.
                This allows the moving object to undergo large unmodeled accelerations, far
                in excess of what would be suggested by typical_acceleration, without
                then experiencing a long lag time where the Kalman filter has to "catches
                up" to the new position.  )asdf"
        )
        .def(py::init<double,double,double>(), py::arg("measurement_noise"), py::arg("typical_acceleration"), py::arg("max_measurement_deviation"))
        .def("measurement_noise",   [](const rect_filter& a){return a.get_left().get_measurement_noise();})
        .def("typical_acceleration",   [](const rect_filter& a){return a.get_left().get_typical_acceleration();})
        .def("max_measurement_deviation",   [](const rect_filter& a){return a.get_left().get_max_measurement_deviation();})
        .def("__call__", [](rect_filter& f, const dlib::rectangle& r){return rectangle(f(r)); }, py::arg("rect"))
        .def("__repr__", print_rect_filter)
        .def(py::pickle(&getstate<type>, &setstate<type>));
    }

    m.def("find_optimal_rect_filter",
        [](const std::vector<rectangle>& rects, const double smoothness ) { return find_optimal_rect_filter(rects, smoothness); },
        py::arg("rects"),
        py::arg("smoothness")=1,
"requires \n\
    - rects.size() > 4 \n\
    - smoothness >= 0 \n\
ensures \n\
    - This function finds the \"optimal\" settings of a rect_filter based on recorded \n\
      measurement data stored in rects.  Here we assume that rects is a complete \n\
      track history of some object's measured positions.  Essentially, what we do \n\
      is find the rect_filter that minimizes the following objective function: \n\
         sum of abs(predicted_location[i] - measured_location[i]) + smoothness*abs(filtered_location[i]-filtered_location[i-1]) \n\
         Where i is a time index. \n\
      The sum runs over all the data in rects.  So what we do is find the \n\
      filter settings that produce smooth filtered trajectories but also produce \n\
      filtered outputs that are as close to the measured positions as possible. \n\
      The larger the value of smoothness the less jittery the filter outputs will \n\
      be, but they might become biased or laggy if smoothness is set really high. "
    /*!
        requires
            - rects.size() > 4
            - smoothness >= 0
        ensures
            - This function finds the "optimal" settings of a rect_filter based on recorded
              measurement data stored in rects.  Here we assume that rects is a complete
              track history of some object's measured positions.  Essentially, what we do
              is find the rect_filter that minimizes the following objective function:
                 sum of abs(predicted_location[i] - measured_location[i]) + smoothness*abs(filtered_location[i]-filtered_location[i-1])
                 Where i is a time index.
              The sum runs over all the data in rects.  So what we do is find the
              filter settings that produce smooth filtered trajectories but also produce
              filtered outputs that are as close to the measured positions as possible.
              The larger the value of smoothness the less jittery the filter outputs will
              be, but they might become biased or laggy if smoothness is set really high.
    !*/
    );

    {
    typedef std::vector<rectangle> type;
    py::bind_vector<type>(m, "rectangles", "An array of rectangle objects.")
        .def(py::init<size_t>(), py::arg("initial_size"))
        .def("clear", &type::clear)
        .def("resize", resize<type>)
        .def("extend", extend_vector_with_python_list<rectangle>)
        .def(py::pickle(&getstate<type>, &setstate<type>));
    }

    {
    typedef std::vector<std::vector<rectangle>> type;
    py::bind_vector<type>(m, "rectangless", "An array of arrays of rectangle objects.")
        .def(py::init<size_t>(), py::arg("initial_size"))
        .def("clear", &type::clear)
        .def("resize", resize<type>)
        .def("extend", extend_vector_with_python_list<rectangle>)
        .def(py::pickle(&getstate<type>, &setstate<type>));
    }

    m.def("translate_rect", [](const rectangle& rect, const point& p){return translate_rect(rect,p);},
" returns rectangle(rect.left()+p.x, rect.top()+p.y, rect.right()+p.x, rect.bottom()+p.y) \n\
  (i.e. moves the location of the rectangle but doesn't change its shape)",
        py::arg("rect"), py::arg("p"));

    m.def("translate_rect", [](const drectangle& rect, const point& p){return translate_rect(rect,p);},
" returns rectangle(rect.left()+p.x, rect.top()+p.y, rect.right()+p.x, rect.bottom()+p.y) \n\
  (i.e. moves the location of the rectangle but doesn't change its shape)",
        py::arg("rect"), py::arg("p"));

    m.def("translate_rect", [](const rectangle& rect, const dpoint& p){return translate_rect(rect,point(p));},
" returns rectangle(rect.left()+p.x, rect.top()+p.y, rect.right()+p.x, rect.bottom()+p.y) \n\
  (i.e. moves the location of the rectangle but doesn't change its shape)",
        py::arg("rect"), py::arg("p"));

    m.def("translate_rect", [](const drectangle& rect, const dpoint& p){return translate_rect(rect,p);},
" returns rectangle(rect.left()+p.x, rect.top()+p.y, rect.right()+p.x, rect.bottom()+p.y) \n\
  (i.e. moves the location of the rectangle but doesn't change its shape)",
        py::arg("rect"), py::arg("p"));

    m.def("shrink_rect", [](const rectangle& rect, long num){return shrink_rect(rect,num);},
" returns rectangle(rect.left()+num, rect.top()+num, rect.right()-num, rect.bottom()-num) \n\
  (i.e. shrinks the given rectangle by shrinking its border by num)",
        py::arg("rect"), py::arg("num"));

    m.def("grow_rect", [](const rectangle& rect, long num){return grow_rect(rect,num);},
"- return shrink_rect(rect, -num) \n\
  (i.e. grows the given rectangle by expanding its border by num)",
        py::arg("rect"), py::arg("num"));

    m.def("scale_rect", [](const rectangle& rect, double scale){return scale_rect(rect,scale);},
"- return scale_rect(rect, scale) \n\
(i.e. resizes the given rectangle by a scale factor)",
        py::arg("rect"), py::arg("scale"));

    m.def("centered_rect", [](const point& p, unsigned long width, unsigned long height) {
        return centered_rect(p, width, height); },
        py::arg("p"), py::arg("width"), py::arg("height"));

    m.def("centered_rects", [](const std::vector<point>& p, unsigned long width, unsigned long height) {
        return centered_rects(p, width, height); },
        py::arg("pts"), py::arg("width"), py::arg("height"));

    m.def("centered_rect", [](const dpoint& p, unsigned long width, unsigned long height) {
        return centered_rect(p, width, height); },
        py::arg("p"), py::arg("width"), py::arg("height"));

    m.def("centered_rect", [](const rectangle& rect, unsigned long width, unsigned long height) {
        return centered_rect(rect, width, height); },
        py::arg("rect"), py::arg("width"), py::arg("height"));

    m.def("centered_rect", [](const drectangle& rect, unsigned long width, unsigned long height) {
        return centered_rect(rect, width, height); },
        py::arg("rect"), py::arg("width"), py::arg("height"));

    m.def("center", [](const rectangle& rect){return center(rect); }, py::arg("rect"),
        "    returns the center of the given rectangle");
    m.def("center", [](const drectangle& rect){return center(rect); }, py::arg("rect"),
        "    returns the center of the given rectangle");
}

// ----------------------------------------------------------------------------------------


/*********************                                                        */
/*! \file sha1_inversion.cpp
 ** \verbatim
 ** Top contributors (to current version):
 **   Dejan Jovanovic, Morgan Deters, Tim King
 ** This file is part of the CVC4 project.
 ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
 ** in the top-level source directory) and their institutional affiliations.
 ** All rights reserved.  See the file COPYING in the top-level source
 ** directory for licensing information.\endverbatim
 **
 ** \brief [[ Add one-line brief description here ]]
 **
 ** [[ Add lengthier description here ]]
 ** \todo document this file
 **/

/*
 * sha1smt.cpp
 *
 *  Created on: Jul 13, 2012
 *      Author: dejan
 */

#include <boost/uuid/sha1.hpp>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>

#include "expr/expr_iomanip.h"
#include "options/language.h"
#include "options/set_language.h"
#include "sha1.hpp"
#include "smt/command.h"
#include "word.h"

using namespace std;
using namespace CVC4;

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

  try {

    // Check the arguments
    if (argc != 3) {
      cerr << "usage: sha1smt message output-file" << std::endl;
      return 1;
    }

    // Get the message to encode and the output file
    string msg = argv[1];
    unsigned msgSize = msg.size();
    ofstream output(argv[2]);
    output << expr::ExprSetDepth(-1) << language::SetLanguage(language::output::LANG_SMTLIB_V2);
    output << SetBenchmarkLogicCommand("QF_BV") << endl;
    output << SetBenchmarkStatusCommand(SMT_SATISFIABLE) << endl;

    // Make the variables the size of the string
    hashsmt::cvc4_uchar8 *cvc4input = new hashsmt::cvc4_uchar8[msgSize];
    for (unsigned i = 0; i < msgSize; ++ i) {
      stringstream ss;
      ss << "x" << i;
      cvc4input[i] = hashsmt::cvc4_uchar8(ss.str());
      output << DeclareFunctionCommand(ss.str(), cvc4input[i].getExpr(), cvc4input[i].getExpr().getType()) << endl;

      // Ouput the solution also
      Expr solution = (cvc4input[i] == hashsmt::cvc4_uchar8(msg.c_str()[i]));
      output << "; " << AssertCommand(solution) << endl;
    }

    // Do the cvc4 encoding
    hashsmt::sha1 cvc4encoder;
    cvc4encoder.process_bytes(cvc4input, msgSize);

    // Get the digest as bitvectors
    hashsmt::cvc4_uint32 cvc4digest[5];
    cvc4encoder.get_digest(cvc4digest);

    // Do the actual sha1 encoding
    boost::uuids::detail::sha1 sha1encoder;
    sha1encoder.process_bytes(msg.c_str(), msgSize);
    unsigned sha1digest[5];
    sha1encoder.get_digest(sha1digest);

    // Create the assertion
    Expr assertion;
    for (unsigned i = 0; i < 5; ++ i) {
      Expr conjunct = (cvc4digest[i] == hashsmt::cvc4_uint32(sha1digest[i]));
      if (i > 0) {
        assertion = assertion.andExpr(conjunct);
      } else {
        assertion = conjunct;
      }
    }
    output << AssertCommand(assertion) << endl;

    // Checksat command
    output << CheckSatCommand() << endl;

    delete cvc4input;

  } catch (CVC4::Exception& e) {
    cerr << e << endl;
  }
}


//!
//! Contains the interface of various IO interop with NumPy.
//!
//! \file io/npy.hpp
//! \author Lachlan McCalman
//! \date January 2014
//! \license General Public License version 3 or later
//! \copyright (c) 2014, NICTA
//!

#pragma once

#include <Eigen/Dense>

#include "cnpy/cnpy.h"

namespace obsidian
{
  namespace io
  {
    //! Read from an NPY file containing a single floating point matrix.
    //!
    //! \param filename The name of the file.
    //! \return The matrix from the file.
    //!
    Eigen::MatrixXd readNPY(const std::string& filename);

    //! Read from an NPY file containing a single integer matrix.
    //!
    //! \param filename The name of the file.
    //! \return The matrix from the file.
    //!
    Eigen::MatrixXi readNPYi(const std::string& filename);

    //! Read from an NPY file containing a single complex matrix.
    //!
    //! \param filename The name of the file.
    //! \return The matrix from the file.
    //!
    Eigen::MatrixXcd readNPYc(const std::string& filename);

    //! Read from a specific key of an NPZ file containing a single
    //! floating point matrix.
    //!
    //! \param filename The name of the file.
    //! \param key The key for the matrix.
    //! \return The matrix from the file.
    //!
    Eigen::MatrixXd readNPZ(const std::string& filename, const std::string& key);

    // NOTE DEPRECATED: use the NpzWriter class instead
    // /**
    //  * Write to a NPY file. This type of a file stores a single matrix.
    //  *
    //  * @param filename The name of the file
    //  * @param matrix The matrix to store
    //  */
    void writeNPY(const std::string& filename, const Eigen::MatrixXd& matrix);
    //
    // /**
    //  * Write to a NPZ file. This type of files can have multiple matrices stored
    //  * as one file. The matrices are indexed by name.
    //  *
    //  * @param filename The name of the NPZ file
    //  * @param mats A map containing keys and their corresponding matrices
    //  * @param overwrite Whether to overwrite any existing file with same filename
    //  */
    void writeNPZ(const std::string &filename, const std::map<std::string, Eigen::MatrixXd> &mats, bool overwrite = false);

    //! Used for writing to an NPZ file.
    //!
    class NpzWriter
    {
      public:
        //! Create a new writer for an NPZ file.
        //!
        //! \param filename The name of the file.
        //!
        NpzWriter(const std::string &filename);

        template<typename T>
        void write(const std::string &name,
            const Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> rowMat)
        {
          const unsigned int shape[] =
          {
            static_cast<unsigned int>(rowMat.rows()),
            static_cast<unsigned int>(rowMat.cols())
          };

          cnpy::npz_save(filename_, name, // name of the file and matrix
              rowMat.data(), // the matrix data
              shape, // the matrix shape
              2, // the number of dimensions
              written_ ? "a" : "w"); // overwrite file on first iteration

          written_ = true;
        }

        template<typename T>
        void writeScalar(const std::string &name, const T value)
        {
          Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> mat(1,
              1);
          mat(0, 0) = value;
          write(name, mat);
        }

    private:
      std::string filename_;
      bool written_ = false;
    };
  }
}


//
// Copyright © 2017 Arm Ltd. All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include <boost/test/unit_test.hpp>
#include "armnnTfParser/ITfParser.hpp"
#include "ParserPrototxtFixture.hpp"

BOOST_AUTO_TEST_SUITE(TensorflowParser)

struct ReshapeFixture : public ParserPrototxtFixture<armnnTfParser::ITfParser>
{
    ReshapeFixture()
    {
        m_Prototext = "node { \n"
            "    name: \"graphInput\" \n"
            "    op: \"Placeholder\" \n"
            "    attr { \n"
            "      key: \"dtype\" \n"
            "      value { \n"
            "        type: DT_FLOAT \n"
            "      } \n"
            "    } \n"
            "    attr { \n"
            "      key: \"shape\" \n"
            "      value { \n"
            "        shape { \n"
            "        } \n"
            "      } \n"
            "    } \n"
            "  } \n"
            "node { \n"
            "  name: \"Reshape/shape\" \n"
            "  op: \"Const\" \n"
            "  attr { \n"
            "    key: \"dtype\" \n"
            "    value { \n"
            "      type: DT_INT32 \n"
            "    } \n"
            "  } \n"
            "  attr { \n"
            "    key: \"value\" \n"
            "    value { \n"
            "      tensor { \n"
            "        dtype: DT_INT32 \n"
            "        tensor_shape { \n"
            "          dim { \n"
            "            size: 2 \n"
            "          } \n"
            "        } \n"
            "        tensor_content: \"\\002\\000\\000\\000\\002\\000\\000\\000\" \n"
            "      } \n"
            "    } \n"
            "  } \n"
            "} \n"
            "node { \n"
            "  name: \"Reshape\" \n"
            "  op: \"Reshape\" \n"
            "  input: \"graphInput\" \n"
            "  input: \"Reshape/shape\" \n"
            "  attr { \n"
            "    key: \"T\" \n"
            "    value { \n"
            "      type: DT_FLOAT \n"
            "    } \n"
            "  } \n"
            "  attr { \n"
            "    key: \"Tshape\" \n"
            "    value { \n"
            "      type: DT_INT32 \n"
            "    } \n"
            "  } \n"
            "} \n";

        SetupSingleInputSingleOutput({1, 4}, "graphInput", "Reshape");
    }
};

BOOST_FIXTURE_TEST_CASE(ParseReshape, ReshapeFixture)
{
    RunTest<2>({ 0.0f, 1.0f, 2.0f, 3.0f }, { 0.0f, 1.0f, 2.0f, 3.0f });
}

BOOST_AUTO_TEST_SUITE_END()


#include <boost/numeric/ublas/storage_sparse.hpp>


#pragma once

#include <boost/dynamic_bitset.hpp>
#include <regex>
#include <vector>

#include "state.hpp"
#include "type.hpp"

enum {
    PAULI_ID_I = 0,
    PAULI_ID_X = 1,
    PAULI_ID_Y = 2,
    PAULI_ID_Z = 3,
};

class DllExport MultiQubitPauliOperator {
private:
    std::vector<UINT> _target_index;
    std::vector<UINT> _pauli_id;
    boost::dynamic_bitset<> _x;
    boost::dynamic_bitset<> _z;

    void set_bit(const UINT pauli_id, const UINT target_index);

public:
    MultiQubitPauliOperator(){};

    MultiQubitPauliOperator(const std::vector<UINT>& target_qubit_index_list,
        const std::vector<UINT>& pauli_id_list)
        : _target_index(target_qubit_index_list), _pauli_id(pauli_id_list) {
        for (ITYPE i = 0; i < pauli_id_list.size(); i++) {
            set_bit(pauli_id_list[i], target_qubit_index_list[i]);
        }
    };

    explicit MultiQubitPauliOperator(std::string pauli_string) {
        std::string pattern = "([IXYZ])\\s*([0-9]+)\\s*";
        std::regex re(pattern);
        std::cmatch result;
        while (std::regex_search(pauli_string.c_str(), result, re)) {
            std::string pauli = result[1].str();
            UINT index = (UINT)std::stoul(result[2].str());
            _target_index.push_back(index);
            UINT pauli_id;
            if (pauli == "I")
                pauli_id = PAULI_ID_I;
            else if (pauli == "X")
                pauli_id = PAULI_ID_X;
            else if (pauli == "Y")
                pauli_id = PAULI_ID_Y;
            else if (pauli == "Z")
                pauli_id = PAULI_ID_Z;
            else
                assert(false && "Error in regex");
            _pauli_id.push_back(pauli_id);
            set_bit(pauli_id, index);
            pauli_string = result.suffix();
        }
        assert(_target_index.size() == _pauli_id.size());
    }

    MultiQubitPauliOperator(
        const boost::dynamic_bitset<>& x, const boost::dynamic_bitset<>& z)
        : _x(x), _z(z) {
        ITYPE index;
        _z.resize(_x.size());
        for (index = 0; index < this->_x.size(); index++) {
            UINT pauli_id;
            if (!this->_x[index] && !this->_z[index])
                pauli_id = PAULI_ID_I;
            else if (!this->_x[index] && this->_z[index])
                pauli_id = PAULI_ID_Z;
            else if (this->_x[index] && !this->_z[index])
                pauli_id = PAULI_ID_X;
            else if (this->_x[index] && this->_z[index])
                pauli_id = PAULI_ID_Y;
            if (pauli_id != PAULI_ID_I) {
                _target_index.push_back(index);
                _pauli_id.push_back(pauli_id);
            }
        }
    };

    ~MultiQubitPauliOperator(){};

    const std::vector<UINT>& get_pauli_id_list() const;
    const std::vector<UINT>& get_index_list() const;
    const boost::dynamic_bitset<>& get_x_bits() const { return this->_x; }
    const boost::dynamic_bitset<>& get_z_bits() const { return this->_z; }

    void add_single_Pauli(UINT qubit_index, UINT pauli_type);

    CPPCTYPE get_expectation_value(const QuantumStateBase* state) const;

    CPPCTYPE get_transition_amplitude(const QuantumStateBase* state_bra,
        const QuantumStateBase* state_ket) const;

    MultiQubitPauliOperator* copy() const;

    bool operator==(const MultiQubitPauliOperator& target) const;

    MultiQubitPauliOperator operator*(
        const MultiQubitPauliOperator& target) const;

    MultiQubitPauliOperator& operator*=(const MultiQubitPauliOperator& target);

    std::string to_string() const;
};

using PauliOperator = MultiQubitPauliOperator;


#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#include "FlatBloofi.cpp"

BOOST_AUTO_TEST_CASE( FlatBloofiTest_SingleInsert ) {
	int bitNo = 9;
	int wSize = 10;

	std::string bitset;
	std::string actualBitset;
	std::vector<BitSet> bloofiMatrix;
	std::unordered_map<int, BloomContainer> bloomMap;

	FlatBloofi* bloofi = new FlatBloofi(wSize, bitNo);
	bloofiMatrix = bloofi->getMatrix();
	BOOST_CHECK_EQUAL(bitNo, bloofiMatrix.size());

	std::vector<BitSet> bsigns;

	// add 001001001 bitset
	bitset = "001001001";
	bsigns.clear();
	bsigns.push_back(BitSet(std::string(bitset)));
	bloofi->mergeFilters(1, bsigns);
	bloofiMatrix = bloofi->getMatrix();
	BOOST_CHECK_EQUAL(1, bloofiMatrix[0].size());

	bloomMap = bloofi->getBloomMap();
	BOOST_CHECK_EQUAL(1, bloomMap.size());
	BOOST_CHECK_EQUAL(1, bloomMap.count(0));
	boost::to_string(bloomMap[0].filter, actualBitset);
	BOOST_CHECK_EQUAL(bitset, actualBitset);

	// add 100100100 bitset
	bitset = "100100100";
	bsigns.clear();
	bsigns.push_back(BitSet(std::string(bitset)));
	bloofi->mergeFilters(2, bsigns);
	bloofiMatrix = bloofi->getMatrix();
	BOOST_CHECK_EQUAL(2, bloofiMatrix[0].size());

	bloomMap = bloofi->getBloomMap();
	BOOST_CHECK_EQUAL(2, bloomMap.size());
	BOOST_CHECK_EQUAL(1, bloomMap.count(1));
	boost::to_string(bloomMap[1].filter, actualBitset);
	BOOST_CHECK_EQUAL(bitset, actualBitset);
}

BOOST_AUTO_TEST_CASE( FlatBloofiTest_MultipleInserts ) {
	int bitNo = 9;
	int wSize = 10;

	std::string bitset;
	std::string actualBitset;
	std::vector<BitSet> bloofiMatrix;
	std::unordered_map<int, BloomContainer> bloomMap;

	FlatBloofi* bloofi = new FlatBloofi(wSize, bitNo);
	std::vector<BitSet> bsigns;

	// add  001001001, 100100100 bitset
	bitset = "101101101";
	bsigns.clear();
	bsigns.push_back(BitSet(std::string("001001001")));
	bsigns.push_back(BitSet(std::string("100100100")));
	bloofi->mergeFilters(1, bsigns);
	bloofiMatrix = bloofi->getMatrix();
	BOOST_CHECK_EQUAL(1, bloofiMatrix[0].size());

	bloomMap = bloofi->getBloomMap();
	BOOST_CHECK_EQUAL(1, bloomMap.size());
	BOOST_CHECK_EQUAL(1, bloomMap.count(0));
	boost::to_string(bloomMap[0].filter, actualBitset);
	BOOST_CHECK_EQUAL(bitset, actualBitset);
}

BOOST_AUTO_TEST_CASE( FlatBloofiTest_MergeInserts ) {
	int bitNo = 9;
	int wSize = 10;

	std::string bitset;
	std::string actualBitset;
	std::vector<BitSet> bloofiMatrix;
	std::unordered_map<int, BloomContainer> bloomMap;

	FlatBloofi* bloofi = new FlatBloofi(wSize, bitNo);
	std::vector<BitSet> bsigns;

	// add 001001001 bitset
	bsigns.clear();
	bsigns.push_back(BitSet(std::string("001001001")));
	bloofi->mergeFilters(1, bsigns);

	// add 100100100 bitset
	bsigns.clear();
	bsigns.push_back(BitSet(std::string("100100100")));
	bloofi->mergeFilters(2, bsigns);

	// add 001001001, 100100100
	bitset = "101101101";
	bsigns.clear();
	bsigns.push_back(BitSet(std::string("001001001")));
	bsigns.push_back(BitSet(std::string("100100100")));
	bloofi->mergeFilters(3, bsigns);

	bloomMap = bloofi->getBloomMap();
	BOOST_CHECK_EQUAL(1, bloomMap.size());
	BOOST_CHECK_EQUAL(1, bloomMap.count(0));
	boost::to_string(bloomMap[0].filter, actualBitset);
	BOOST_CHECK_EQUAL(bitset, actualBitset);
}


// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2018-2020, Oracle and/or its affiliates.

// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GEOMETRY_STRATEGY_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_ENVELOPE_MULTIPOINT_HPP

#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>

#include <boost/geometry/core/tags.hpp>

#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>

#include <boost/geometry/strategy/cartesian/envelope.hpp>
#include <boost/geometry/strategy/cartesian/envelope_point.hpp>
#include <boost/geometry/strategy/cartesian/expand_point.hpp>

namespace boost { namespace geometry
{

namespace strategy { namespace envelope
{

class cartesian_multipoint
{
public:
    template <typename MultiPoint, typename Box>
    static inline void apply(MultiPoint const& multipoint, Box& mbr)
    {
        apply(boost::begin(multipoint), boost::end(multipoint), mbr);
    }

private:
    template <typename Iterator, typename Box>
    static inline void apply(Iterator it,
                             Iterator last,
                             Box& mbr)
    {
        geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(mbr);

        if (it != last)
        {
            strategy::envelope::cartesian_point::apply(*it, mbr);

            for (++it; it != last; ++it)
            {
                strategy::expand::cartesian_point::apply(mbr, *it);
            }
        }
    }
};

#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

namespace services
{

template <typename CalculationType>
struct default_strategy<multi_point_tag, cartesian_tag, CalculationType>
{
    typedef strategy::envelope::cartesian_multipoint type;
};

} // namespace services

#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

}} // namespace strategy::envelope

}} // namespace boost::geometry

#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_ENVELOPE_MULTIPOINT_HPP


// Copyright 2005 The Trustees of Indiana University.

// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//  Authors: Douglas Gregor
//           Andrew Lumsdaine
#include <boost/graph/dijkstra_shortest_paths.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/python.hpp>

namespace boost { namespace graph { namespace python {

using boost::python::object;

#define BGL_PYTHON_VISITOR maybe_dijkstra_visitor
#define BGL_PYTHON_EVENTS_HEADER <boost/graph/python/dijkstra_events.hpp>
#include <boost/graph/python/visitor.hpp>
#undef BGL_PYTHON_EVENTS_HEADER
#undef BGL_PYTHON_VISITOR

template<typename Graph>
void
dijkstra_shortest_paths
  (const Graph& g,
   typename graph_traits<Graph>::vertex_descriptor s,
   vector_property_map<
     typename graph_traits<Graph>::vertex_descriptor,
     typename property_map<Graph, vertex_index_t>::const_type>* in_predecessor,
   vector_property_map<
     float,
     typename property_map<Graph, vertex_index_t>::const_type>* in_distance,
   vector_property_map<
     float,
     typename property_map<Graph, edge_index_t>::const_type>* in_weight,
   boost::python::object in_visitor,
   vector_property_map<
     default_color_type,
     typename property_map<Graph, vertex_index_t>::const_type>* in_color)
{
  typedef typename property_map<Graph, vertex_index_t>::const_type
    VertexIndexMap;
  typedef typename property_map<Graph, edge_index_t>::const_type
    EdgeIndexMap;
  typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
  typedef vector_property_map<Vertex, VertexIndexMap> PredecessorMap;
  typedef vector_property_map<float, VertexIndexMap> DistanceMap;
  typedef vector_property_map<default_color_type, VertexIndexMap> ColorMap;
  typedef vector_property_map<float, EdgeIndexMap> WeightMap;

  PredecessorMap predecessor =
    in_predecessor? *in_predecessor
    : PredecessorMap(num_vertices(g), get(vertex_index, g));

  DistanceMap distance =
    in_distance? *in_distance
    : DistanceMap(num_vertices(g), get(vertex_index, g));

  ColorMap color =
    in_color? *in_color
    : ColorMap(num_vertices(g), get(vertex_index, g));

  WeightMap weight =
    in_weight? *in_weight
    : WeightMap(num_edges(g), get(edge_index, g));

  if (!in_weight)
    BGL_FORALL_EDGES_T(e, g, Graph) put(weight, e, 1.0f);

  if (in_visitor != object()) {
    boost::dijkstra_shortest_paths
      (g, s, boost::visitor(maybe_dijkstra_visitor(in_visitor)).
       predecessor_map(predecessor).
       distance_map(distance).
       weight_map(weight).
       color_map(color));
  } else {
    boost::dijkstra_shortest_paths
      (g, s,
       predecessor_map(predecessor).
       distance_map(distance).
       weight_map(weight).
       color_map(color));
  }
}

} } } // end namespace boost::graph::python


/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Sylko Olzscher
 *
 */
#ifndef CYNG_IO_BYTES_HPP
#define CYNG_IO_BYTES_HPP

#include <cyng/io.h>
#include <iostream>
#include <iomanip>
#include <type_traits>
#include <boost/io/ios_state.hpp>
#include <boost/numeric/conversion/cast.hpp>

namespace cyng
{

	template <typename T>
	std::string bytes_to_str(T v)
	{
		static_assert(std::is_integral<T>::value, "integral required");
		static_assert(std::is_unsigned<T>::value, "unsigned required");

		const char* units[] = { "Bytes", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
		std::size_t idx = 0;
		auto d = boost::numeric_cast<double>(v);
		while ((d >= 1024) && (idx < 8)) {
			d /= 1024;
			idx++;
		}

		std::stringstream ss;
		ss.flags(std::ios::fixed);
		ss.precision(2);

		ss << std::dec << d << ' ' << units[idx];
		return ss.str();
	}

}

#endif


/**
 * @file observer.hpp
 * @copyright Copyright (c) 2020 Nicolas Pope, MIT License
 * @author Nicolas Pope
 */

#pragma once

#include "defines.hpp"

#include <voltu/types/frame.hpp>
#include <voltu/types/property.hpp>
#include <memory>
#include <Eigen/Eigen>

namespace voltu
{

enum class ObserverProperty
{
	kInvalid			= 0,
	kBackgroundColour	= 1001,  // String or Int
	kPointCloudMode		= 1002,  // Bool
	kProjection			= 1003,  // Enum or Int
	kAntiAliasing		= 1004,  // Bool
	kDepthOnly			= 1005,  // Bool
	kColourSources		= 1006,  // Bool
	kName				= 1007,  // String
};

class Observer
{
public:
	virtual ~Observer() = default;

	PY_API virtual void setResolution(uint32_t w, uint32_t h) = 0;

	PY_API virtual void setFocalLength(uint32_t f) = 0;

	PY_API virtual void setStereo(bool) = 0;

	PY_API virtual bool waitCompletion(int timeout) = 0;

	PY_API virtual void submit(const voltu::FramePtr&) = 0;

	PY_API virtual void setPose(const Eigen::Matrix4f &) = 0;

	PY_API PY_RV_LIFETIME_PARENT virtual voltu::FramePtr getFrame() = 0;

	PY_API virtual voltu::PropertyPtr property(voltu::ObserverProperty) = 0;

	//PY_API virtual voltu::PropertyPtr property(const std::string &name) = 0;
};

typedef std::shared_ptr<Observer> ObserverPtr;

}


#include <numpy_eigen/boost_python_headers.hpp>
#include <boost/python/operators.hpp>
#include <aslam/Time.hpp>

// static Time now();
// double toSec()  const { return (double)sec + 1e-9*(double)nsec; };
// T& fromSec(double t) { sec = (uint32_t)floor(t); nsec = (uint32_t)boost::math::round((t-sec) * 1e9);  return *static_cast<T*>(this);}

// double toSec() const { return (double)sec + 1e-9*(double)nsec; };
// int64_t toNSec() const {return (int64_t)sec*1000000000ll + (int64_t)nsec;  };
// T& fromSec(double t);

void exportTimeAndDuration()
{
  using namespace aslam;
  using namespace boost::python;

  class_<aslam::Time>("Time", "A class to represent time. Initialize with Time(), Time(seconds), or Time(sec, nsec)")
    .def(init<>())
    .def(init<double>())
    .def(init<int,int>())
    .def("now", &Time::now, "Get the current time")
    .staticmethod("now")
    .def("toSec", &Time::toSec, "Convert the current time to seconds")
    .def("fromSec", &Time::fromSec, return_value_policy<copy_non_const_reference>(), "Set the time from seconds")
    .def("toNSec", &Time::toNSec, "Convert the current time to nanoseconds")
    .def("fromNSec", &Time::fromNSec, return_value_policy<copy_non_const_reference>(), "Set the time from nanoseconds")
    .def(self - self)
    .def(self + Duration())
    .def(self - Duration())
    .def(self += Duration())
    .def(self -= Duration())
    .def(self == self)
    .def(self != self)
    .def(self > self)
    .def(self < self)
    .def(self >= self)
    .def(self <= self)
    .def("isZero", &Time::isZero, "Is this time zero?")
    ;

  class_<aslam::Duration>("Duration", "A class to represent a time duration. Initialize with Duration(), Duration(seconds), or Duration(sec, nsec)")
    .def(init<>())
    .def(init<double>())
    .def(init<int,int>())
    .def("toSec", &Duration::toSec, "Convert the current time to seconds")
    .def("fromSec", &Duration::fromSec, return_value_policy<copy_non_const_reference>(), "Set the time from seconds")
    .def("toNSec", &Duration::toNSec, "Convert the current time to nanoseconds")
    .def("fromNSec", &Duration::fromNSec, return_value_policy<copy_non_const_reference>(), "Set the time from nanoseconds")
    .def(self - self)
    .def(self + self)
    .def(self += self)
    .def(self -= self)
    .def(self == self)
    .def(self != self)
    .def(self > self)
    .def(self < self)
    .def(self >= self)
    .def(self <= self)
    .def("isZero", &Duration::isZero, "Is this duration zero?")
    ;

}


/*
==============================================================================
Kratos
A General Purpose Software for Multi-Physics Finite Element Analysis
Version 1.0 (Released on march 05, 2007).

Copyright 2007
Pooyan Dadvand, Riccardo Rossi
pooyan@cimne.upc.edu
rrossi@cimne.upc.edu
CIMNE (International Center for Numerical Methods in Engineering),
Gran Capita' s/n, 08034 Barcelona, Spain

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

Distribution of this code for  any  commercial purpose  is permissible
ONLY BY DIRECT ARRANGEMENT WITH THE COPYRIGHT OWNER.

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

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

==============================================================================
*/

//
//   Project Name:        Kratos
//   Last modified by:    $Author: janosch $
//   Date:                $Date: 2007-12-13 14:50:05 $
//   Revision:            $Revision: 1.4 $
//
//

// System includes
#include <cstddef>

// External includes
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

// Project includes
#include "includes/define.h"
#include "integration/quadrature.h" // to bo changed to the new version below.
#include "integration/gauss_legendre_integration_points.h"
//#include "quadratures/gauss_legendre_integration_points.h"
//#include "quadratures/quadrature.h"
#include "python/container_from_python.h"

namespace Kratos
{

	template<std::size_t TDimension>
  std::stringstream& operator << (std::stringstream& rOStream,
				  std::vector<IntegrationPoint<TDimension> > const & rThis)
    {
 	typename std::vector<IntegrationPoint<TDimension> >::size_type i;
 	for(i = 0 ; i < rThis.size() - 1 ; i++)
	  rOStream << rThis[i] << " , " << std::endl;
 	rOStream << rThis[i];
      return rOStream;
    }

namespace Python
{

  using namespace boost::python;

  template<class TArrayType>
  void AddIntegrationPointsArray(std::string const& rArrayName, TArrayType const & Dummy)
  {
    ContainerFromPython< TArrayType >();

     class_<TArrayType>(rArrayName.c_str(), init<int>())
	.def(init<const TArrayType&>())
	.def(vector_indexing_suite<TArrayType>())
 	.def(self_ns::str(self))
	;

  }

  void  AddQuadraturesToPython()
  {
    AddIntegrationPointsArray("IntegrationPointsArray", Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints1,1,Kratos::IntegrationPoint<3> >::IntegrationPointsArrayType());
    //AddIntegrationPointsArray("IntegrationPoint2DsArray", Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints<1>,2,Kratos::IntegrationPoint<3> >::IntegrationPointsArrayType());
    //AddIntegrationPointsArray("IntegrationPoint3DsArray", Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints<1>,3,Kratos::IntegrationPoint<3> >::IntegrationPointsArrayType());
    //AddIntegrationPointsArray("IntegrationPoint4DsArray", Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints<1>,4,Kratos::IntegrationPoint<3> >::IntegrationPointsArrayType());

    scope().attr("GaussLegendreQuadrature1D1") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints1,1,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature1D2") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints2,1,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature1D3") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints3,1,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature2D1") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints1,2,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature2D2") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints2,2,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature2D3") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints3,2,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature3D1") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints1,3,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature3D2") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints2,3,Kratos::IntegrationPoint<3> >::IntegrationPoints();
    scope().attr("GaussLegendreQuadrature3D3") = Kratos::Quadrature<Kratos::GaussLegendreIntegrationPoints3,3,Kratos::IntegrationPoint<3> >::IntegrationPoints();
  }

}  // namespace Python.

} // Namespace Kratos


/*!
*	@file	psalm.cpp
*	@brief	Main file for "psalm"
*
*	"psalm" (Pretty Subdivision ALgorithms on Meshes) is a CLI tool that
*	implements the Doo-Sabin and Catmull-Clark subdivision schemes.
*/

#include <iostream>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <set>

#include <boost/program_options.hpp>

#include <cerrno>
#include <cstring>

#include <unistd.h>
#include <getopt.h>
#include <libgen.h>

#include "SubdivisionAlgorithms/CatmullClark.h"
#include "SubdivisionAlgorithms/DooSabin.h"
#include "SubdivisionAlgorithms/Loop.h"
#include "SubdivisionAlgorithms/Liepa.h"

#include "FairingAlgorithms/FairingAlgorithm.h"

// FIXME: This should be conditional
#if 0
  #include "FairingAlgorithms/CurvatureFlow.h"
#endif

#include "mesh.h"

psalm::mesh scene_mesh;
std::string input;
std::string output;

namespace po = boost::program_options;

/*!
*	Reads a map of weights for a sudivision algorithm from a file. Each
*	line of the file must be of the following form:
*
*		<k> <a_1> ... <a_k>
*
*	Where <k> is the number of vertices for a face and <a_i> are the
*	weights that are used for the vertices of the face. The weights are
*	supposed to be arranged in counterclockwise order.
*
*	@param filename Filename of weights map
*	@return Associative array for quickly looking up the weights.
*/

psalm::weights_map load_weights_map(const std::string& filename)
{
	psalm::weights_map res;

	std::ifstream in;
	errno = 0;
	in.open(filename.c_str());

	if(!in.good() || errno)
	{
		std::string error = strerror(errno);
		std::cerr	<< "psalm: Could not load weights map file \""
				<< filename << "\": "
				<< error << "\n";

		return(res);
	}

	std::string line;
	std::istringstream converter;
	while(getline(in, line))
	{
		converter.clear();
		converter.str(line);

		std::vector<double> weights;
		size_t k = 0;

		// Read k and try to read k weights afterwards

		converter >> k;
		if(converter.fail())
		{
			std::cerr	<< "psalm: Unable to read number of weights "
					<< "from line \"" << line << "\"\n";
			return(res);
		}

		double w = 0.0;
		for(size_t i = 0; i < k; i++)
		{
			converter >> w;
			if(converter.fail())
			{
				std::cerr	<< "psalm: Unable to read weights "
						<< "from line \"" << line << "\"\n";
				return(res);
			}

			weights.push_back(w);
		}

		res[k] = weights;
	}

	return(res);
}

/*!
*	Parses a string of comma-separated numbers.
*
*	@param	argument Argument string
*	@return Set of numbers.
*/

std::set<size_t> parse_value_string(std::string argument)
{
	std::set<size_t> res;

	std::istringstream val_stream(argument);
	std::istringstream converter;
	std::string val_str;
	while(getline(val_stream, val_str, ','))
	{
		converter.clear();
		converter.str(val_str);

		size_t value;
		converter >> value;
		if(converter.fail())
		{
			std::cerr << "psalm: Unable to convert \"" << val_str << "\" to a number.\n";
			return(res);
		}

		res.insert(value);
	}

	return(res);
}

/*!
*	Handles user interaction.
*
*	@param argc Number of command-line arguments
*	@param argv Vector of command-line arguments
*/

int main(int argc, char* argv[])
{
	psalm::mesh::file_type type = psalm::mesh::TYPE_EXT;

	std::set<size_t> remove_faces;
	std::set<size_t> remove_vertices;
	psalm::weights_map extra_weights;

	size_t steps	= 0;

	psalm::SubdivisionAlgorithm* subdivision_algorithm	= NULL;
	psalm::FairingAlgorithm* fairing_algorithm		= NULL;

	// Add general program options

	po::options_description general("General", 80);
	general.add_options()
		(	"algorithm,a",
			po::value<std::string>(),
			"Selects subdivision algorithm to use on the input mesh. Valid values:\n"\
			"* catmull-clark, catmull, clark, cc [default]\n"\
			"* doo-sabin, doo, sabin, ds\n"\
			"* loop, l")

		(	"type,t",
			po::value<std::string>(),
			"Selects type of input data. Valid values:\n"\
			"* ply (Stanford PLY files)\n"\
			"* obj (Wavefront OBJ files)\n"\
			"* off (Geomview object files)")

		(	"output,o",
			po::value<std::string>(&output)->default_value(""),
			"Sets output file")

		(	"steps,n",
			po::value<size_t>(&steps),
			"Sets number of subdivision steps to perform on the input mesh.")

		(	"statistics,s",
			"Prints statistics to STDERR")

		(	"help,h",
			"Shows this screen");

	// Add tuning program options

	po::options_description tuning("Algorithm tuning", 80);
	tuning.add_options()
		(	"preserve-boundaries,p",
			"Forces subdivision algorithms to preserve the original boundaries of a mesh. "\
			"This is especially useful for open meshes. This flag is not taken into "\
			"account by every subdivision algorithm.")

		(	"handle-creases,c",
			"Subdivides crease and boundary edges whenever the algorithm supports this. "\
			"For the Catmull-Clark scheme, for example, midpoints of edges are used for "\
			"the new control points")

		(	"geometric,g",
			"Forces algorithms to compute new points using "\
			"geometric methods and forbids the use of parametric (i.e. weight-based) ones.")

		(	"b-spline-weights,b",
			"Forces algorithms to use the B-spline weights in regular cases, thereby "\
			"overriding any other weights scheme.")

		(	"extra-weights,e",
			po::value<std::string>(),
			"Overrides default weights of subdivision schemes by reading them from <arg>. "\
			"The exact format of this file depends on the subdivision algorithm that is used.")

		(	"weights,w",
			po::value<std::string>(),
			"Selects type of weights that are used for the subdivision scheme. Algorithms "\
			"may ignore unknown values. Valid values:\n"\
			"* catmull-clark, catmull, clark, cc\n"\
			"* default\n"\
			"* degenerate\n"\
			"* doo-sabin, doo, sabin, ds\n")

		(	"fair,f",
			"Performs a fairing step after working with the mesh.");

	// Add pruning program options

	po::options_description pruning("Pruning", 80);
	pruning.add_options()
		(	"remove-faces",
			po::value<std::string>(),
			"Remove faces whose number of sides matches one of the numbers in the list. "\
			"Use commas to separate list values.")

		(	"remove-vertices",
			po::value<std::string>(),
			"Remove vertices whose valency matches one of the numbers in the list. "\
			"Use commas to separate list values.");

	// Add hidden program options that are used for multiple input files

	po::options_description hidden_options("");
	hidden_options.add_options()
		(	"input",
			po::value< std::vector<std::string> >());

	// Describe visible options of the program and parse the command-line
	// using _all_ available options

	po::options_description visible_options("Usage: psalm [arguments] [files]");
	po::options_description all_options("");

	visible_options.add(general);
	visible_options.add(tuning);
	visible_options.add(pruning);

	all_options.add(visible_options);
	all_options.add(hidden_options);

	po::positional_options_description p;
	p.add("input", -1);

	po::variables_map vm;
	try
	{
		po::store(po::command_line_parser(argc, argv)	.options(all_options)
								.positional(p)
								.run(), vm);
		po::notify(vm);
	}
	catch(const boost::program_options::error& e)
	{
		std::cerr << "psalm: Options error: " << e.what() << "\n";
		return(-1);
	}

	// Actual handling of command-line options; mostly, parameters are set

	if(vm.count("help"))
	{
		std::cerr << all_options << "\n";
		return(0);
	}

	if(vm.count("type"))
	{
		std::string type_str = vm["type"].as<std::string>();
		std::transform(type_str.begin(), type_str.end(), type_str.begin(), (int(*)(int)) tolower);
		if(type_str == "ply")
			type = psalm::mesh::TYPE_PLY;
		else if(type_str == "obj")
			type = psalm::mesh::TYPE_OBJ;
		else if(type_str == "off")
			type = psalm::mesh::TYPE_OFF;
		else
		{
			std::cerr << "psalm: \"" << type_str << "\" is an unknown mesh data type.\n";
			return(-1);
		}
	}

	// As there is currently only _one_ fairing algorithm, there is really
	// not much choice here
	if(vm.count("fair"))
        {
// FIXME: Should be conditionally disabled...
#if 0
		fairing_algorithm = new psalm::CurvatureFlow();
#endif
        }

	// We use this instance to create an instance of a subdivision
	// algorithm class. Further class parameters are set _afterwards_,
	// sometimes depending on the type of subdivision algorithm.
	if(vm.count("algorithm"))
	{
		std::string algorithm_str = vm["algorithm"].as<std::string>();
		std::transform(algorithm_str.begin(), algorithm_str.end(), algorithm_str.begin(), (int(*)(int)) tolower);

		if(	algorithm_str == "catmull-clark"	||
			algorithm_str == "catmull"		||
			algorithm_str == "clark"		||
			algorithm_str == "cc")
		{
			subdivision_algorithm = new psalm::CatmullClark();
		}
		else if(algorithm_str == "doo-sabin"		||
			algorithm_str == "doo"			||
			algorithm_str == "sabin"		||
			algorithm_str == "ds")
		{
			subdivision_algorithm = new psalm::DooSabin();
		}
		else if(algorithm_str == "loop"	||
			algorithm_str == "l")
		{
			subdivision_algorithm = new psalm::Loop();
		}
		else if(algorithm_str == "liepa")
		{
			subdivision_algorithm = new psalm::Liepa();
		}
		else
		{
			std::cerr << "psalm: \"" << algorithm_str << "\" is an unknown algorithm.\n";
			return(-1);
		}
	}

	// Only applicable if the subdivision algorithm is the Doo-Sabin
	// subdivision scheme
	if(vm.count("extra-weights"))
	{
		psalm::DooSabin* ds_algorithm = dynamic_cast<psalm::DooSabin*>(subdivision_algorithm);
		if(ds_algorithm)
		{
			extra_weights = load_weights_map(vm["extra-weights"].as<std::string>());
			if(extra_weights.size() == 0)
			{
				std::cerr << "psalm: Unwilling to continue with empty weights file.\n";
				return(-1);
			}

			ds_algorithm->set_custom_weights(extra_weights);
		}
		else
			std::cerr << "psalm: Warning: Weights file specified, but no Doo-Sabin algorithm.\n";
	}

	if(vm.count("weights"))
	{
		std::string weights_str = vm["weights"].as<std::string>();
		std::transform(weights_str.begin(), weights_str.end(), weights_str.begin(), (int(*)(int)) tolower);

		if(	weights_str == "catmull-clark"	||
			weights_str == "catmull"	||
			weights_str == "clark"		||
			weights_str == "cc")
		{
			subdivision_algorithm->set_weights(psalm::SubdivisionAlgorithm::catmull_clark);
		}
		else if(weights_str == "doo-sabin"	||
			weights_str == "doo"		||
			weights_str == "sabin"		||
			weights_str == "ds")
		{
			subdivision_algorithm->set_weights(psalm::SubdivisionAlgorithm::doo_sabin);
		}
		else if(weights_str == "degenerate")
		{
			subdivision_algorithm->set_weights(psalm::SubdivisionAlgorithm::degenerate);
		}
		else
		{
			std::cerr << "psalm: \"" << weights_str << "\" is an unknown weight scheme.\n";
			return(-1);
		}
	}

	// This is parsed using an external function because the parameter
	// string consists of comma-separated values

	if(vm.count("remove-faces"))
		remove_faces = parse_value_string(vm["remove-faces"].as<std::string>());

	if(vm.count("remove-vertices"))
		remove_vertices = parse_value_string(vm["remove-vertices"].as<std::string>());

	// Various small flags

	if(vm.count("handle-creases"))
		subdivision_algorithm->set_crease_handling_flag();

	if(vm.count("geometric"))
		subdivision_algorithm->set_geometric_point_creation_flag();

	if(vm.count("preserve-boundaries"))
		subdivision_algorithm->set_boundary_preservation_flag();

	if(vm.count("statistics"))
		subdivision_algorithm->set_statistics_flag();

	// This only works for B-spline-based subdivision algorithms, hence the
	// dynamic_cast.
	if(vm.count("b-spline-weights"))
	{
		psalm::BsplineSubdivisionAlgorithm* b_spline_algorithm = dynamic_cast<psalm::BsplineSubdivisionAlgorithm*>(subdivision_algorithm);
		if(b_spline_algorithm)
			b_spline_algorithm->set_bspline_weights_usage();
	}

	// Read further command-line parameters; these are all supposed to be
	// input files. If the user already specified an output file, only one
	// input file will be accepted.

	std::vector<std::string> files;
	if(vm.count("input"))
	{
		files = vm["input"].as< std::vector<std::string> >();
		if(output.length() != 0 && files.size() > 1)
		{
			std::cerr << "psalm: Output file specified, but more than one input file present.\n";
			return(-1);
		}

	}

	// Replace the special file "-" by an empty string, thereby signalling
	// that standard input and standard output are to be used as file
	// streams.

	for(std::vector<std::string>::iterator it = files.begin(); it != files.end(); it++)
	{
		if(it->length() == 1 && (*it)[0] == '-')
			*it = "";
	}

	bool output_set = (output.length() > 0);
	if(output.length() == 1 && output[0] == '-')
		output = "";

	// Try to read from STDIN if no input files have been specified
	if(files.size() == 0)
		files.push_back("");

	// Apply subdivision algorithm to all files

	for(std::vector<std::string>::iterator it = files.begin(); it != files.end(); it++)
	{
		scene_mesh.load(*it, type);

		// It is possible that the user did not choose a subdivision
		// algorithm. psalm tries to work as a mesh converter in this
		// instance.
		if(subdivision_algorithm)
			subdivision_algorithm->apply_to(scene_mesh, steps);

		// Ditto for the fairing algorithm.
		if(fairing_algorithm)
			fairing_algorithm->apply_to(scene_mesh);

		scene_mesh.prune(remove_faces, remove_vertices);

		// If an output file has been set (even if it is empty), it
		// will be used.
		if(output_set)
			scene_mesh.save(output, type);

		// If no output file has been set and the input file name is
		// not empty, the output will be written to a file.
		else if(it->length() > 0)
		{
			size_t ext_pos = (*it).find_last_of(".");
			if(ext_pos == std::string::npos)
				scene_mesh.save(*it+".subdivided", type);
			else
				scene_mesh.save( (*it).substr(0, ext_pos) + "_subdivided"
						+(*it).substr(ext_pos));
		}

		// If no output file has been set and the input file name is
		// empty, the output will be written to STDOUT.
		else
			scene_mesh.save("", type);
	}

	delete(subdivision_algorithm);
	delete(fairing_algorithm);

	return(0);
}


/*
  [auto_generated]
  boost/numeric/odeint/util/unit_helper.hpp

  [begin_description]
  Get and set the value of a unit.
  [end_description]

  Copyright 2012-2013 Karsten Ahnert
  Copyright 2012-2013 Mario Mulansky

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE_1_0.txt or
  copy at http://www.boost.org/LICENSE_1_0.txt)
*/

#ifndef BOOST_NUMERIC_ODEINT_UTIL_UNIT_HELPER_HPP_INCLUDED
#define BOOST_NUMERIC_ODEINT_UTIL_UNIT_HELPER_HPP_INCLUDED

#ifndef __CUDACC__
#include <boost/units/quantity.hpp>
#include <boost/units/get_dimension.hpp>
#include <boost/units/get_system.hpp>
#endif

namespace boost {
namespace numeric {
namespace odeint {

namespace detail {

    template<class T , class Enabler = void >
    struct get_unit_value_impl
    {
        static T value(const T &t)
        {
            return t;
        }
        typedef T result_type;
    };

#ifndef __CUDACC__
    template<class Unit , class T>
    struct get_unit_value_impl< boost::units::quantity< Unit , T> >
    {
        static T value( const boost::units::quantity< Unit , T> &t )
        {
            return t.value();
        }
        typedef T result_type;
    };
#endif

    template<class T , class V , class Enabler = void >
    struct set_unit_value_impl
    {
        static void set_value(T &t , const V &v)
        {
            t = v;
        }
    };

#ifndef __CUDACC__
    template<class Unit , class T , class V>
    struct set_unit_value_impl<boost::units::quantity<Unit , T> , V>
    {
        static void set_value(boost::units::quantity<Unit , T> &t , const V &v)
        {
            t = boost::units::quantity<Unit , T>::from_value(v);
        }
    };
#endif

} // namespace detail

    template<class T>
    typename detail::get_unit_value_impl<T>::result_type get_unit_value(const T &t)
    {
        return detail::get_unit_value_impl<T>::value(t);
    }

    template<class T , class V>
    void set_unit_value(T &t , const V &v)
    {
        return detail::set_unit_value_impl<T , V>::set_value(t , v);
    }

    template< class T >
    struct unit_value_type
    {
        typedef T type;
    };

#ifndef __CUDACC__
    template< class Unit , class Y >
    struct unit_value_type< boost::units::quantity< Unit , Y > >
    {
        typedef Y type;
    };
#endif

    template< typename Time >
    struct inverse_time
    {
        typedef Time type;
    };

#ifndef __CUDACC__
    template< typename Unit , typename Value >
    struct inverse_time< boost::units::quantity< Unit , Value > >
    {
        typedef boost::units::quantity< Unit , Value > time_type;
        typedef typename boost::units::get_dimension< time_type >::type dimension;
        typedef typename boost::units::get_system< time_type >::type system;
        typedef typename boost::mpl::divides< boost::units::dimensionless_type , dimension >::type inv_dimension;
        typedef boost::units::unit< inv_dimension , system > inv_unit;
        typedef boost::units::quantity< inv_unit , Value > type;
    };
#endif

} // namespace odeint
} // namespace numeric
} // namespace boost

#endif // BOOST_NUMERIC_ODEINT_UTIL_UNIT_HELPER_HPP_INCLUDED