<commit_before>/**********************************************************************/
/* Copyright 2014 RCF                                                 */
/*                                                                    */
/* 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.                                 */
/**********************************************************************/

#ifndef HPP_OPTIONS_DEFINED
#define HPP_OPTIONS_DEFINED

/**
 * @file  Options.hpp
 * @brief Define options to be used in the game.
 */

// C Libraries
#include <getopt.h>

/**
 * @namespace Options
 * @brief All functions and variables related to Transport problem.
 *
 * Define the prototype to a function to parse arguments and
 * set variables to be used by the Transport problem
 */
struct Options
{
    bool verbose;
    std::string output;

    Options() : verbose{false}, output{} {}

    /**
     * @brief Parse arguments came from the command line.
     *
     * Set game options and flags, using as background
     * the getopt.h package.
     *
     * @param argc Number of arguments in the command line
     * @param argv Array of string with the arguments
     */
    void parse_args(int argc, char **argv);
};

#endif
<commit_msg>Changing comments<commit_after>/**********************************************************************/
/* Copyright 2014 RCF                                                 */
/*                                                                    */
/* 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.                                 */
/**********************************************************************/

#ifndef HPP_OPTIONS_DEFINED
#define HPP_OPTIONS_DEFINED

/**
 * @file  Options.hpp
 * @brief Define options to be used in the game.
 */

// C Libraries
#include <getopt.h>

/**
 * @class Options
 * @brief All functions and variables related to Transport problem.
 *
 * Define the prototype to a function to parse arguments and
 * set variables to be used by the Transport problem
 */
struct Options
{
    bool verbose;
    std::string output;

    Options() : verbose{false}, output{} {}

    /**
     * @brief Parse arguments came from the command line.
     *
     * Set game options and flags, using as background
     * the getopt.h package.
     *
     * @param argc Number of arguments in the command line
     * @param argv Array of string with the arguments
     */
    void parse_args(int argc, char **argv);
};

#endif
<|endoftext|>


<commit_before>/*

Copyright (c) 2007-2012, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_TIME_HPP_INCLUDED
#define TORRENT_TIME_HPP_INCLUDED

#include <boost/version.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/ptime.hpp"
#include <boost/cstdint.hpp>
#include <string>

// OVERVIEW
//
// This section contains fundamental time types used internall by
// libtorrent and exposed through various places in the API. The two
// basic types are ``ptime`` and ``time_duration``. The first represents
// a point in time and the second the difference between two points
// in time.
//
// The internal representation of these types is implementation defined
// and they can only be constructed via one of the construction functions
// that take a well defined time unit (seconds, minutes, etc.). They can
// only be turned into well defined time units by the accessor functions
// (total_microseconds(), etc.).
//
// .. note::
// 	In a future version of libtorrent, these types will be replaced
// 	by the standard timer types from ``std::chrono``.

namespace libtorrent
{
	char const* time_now_string();
	std::string log_time();

	TORRENT_EXPORT ptime const& time_now();
	TORRENT_EXPORT ptime time_now_hires();

	TORRENT_EXPORT ptime min_time();
	TORRENT_EXPORT ptime max_time();

#if defined TORRENT_USE_BOOST_DATE_TIME || defined TORRENT_USE_QUERY_PERFORMANCE_TIMER

	TORRENT_EXPORT time_duration seconds(int s);
	TORRENT_EXPORT time_duration milliseconds(int s);
	TORRENT_EXPORT time_duration microsec(int s);
	TORRENT_EXPORT time_duration minutes(int s);
	TORRENT_EXPORT time_duration hours(int s);

	TORRENT_EXPORT int total_seconds(time_duration td);
	TORRENT_EXPORT int total_milliseconds(time_duration td);
	TORRENT_EXPORT boost::int64_t total_microseconds(time_duration td);

#elif TORRENT_USE_CLOCK_GETTIME || TORRENT_USE_SYSTEM_TIME || TORRENT_USE_ABSOLUTE_TIME

	// hidden
	inline int total_seconds(time_duration td)
	{ return td.diff / 1000000; }
	// hidden
	inline int total_milliseconds(time_duration td)
	{ return td.diff / 1000; }
	// hidden
	inline boost::int64_t total_microseconds(time_duration td)
	{ return td.diff; }

	// hidden
	inline time_duration microsec(boost::int64_t s)
	{ return time_duration(s); }
	// hidden
	inline time_duration milliseconds(boost::int64_t s)
	{ return time_duration(s * 1000); }
	// hidden
	inline time_duration seconds(boost::int64_t s)
	{ return time_duration(s * 1000000); }
	// hidden
	inline time_duration minutes(boost::int64_t s)
	{ return time_duration(s * 1000000 * 60); }
	// hidden
	inline time_duration hours(boost::int64_t s)
	{ return time_duration(s * 1000000 * 60 * 60); }

#endif // TORRENT_USE_CLOCK_GETTIME

}

#endif // TORRENT_TIME_HPP_INCLUDED

<commit_msg>export time_now_string for unit tests<commit_after>/*

Copyright (c) 2007-2012, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_TIME_HPP_INCLUDED
#define TORRENT_TIME_HPP_INCLUDED

#include <boost/version.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/ptime.hpp"
#include <boost/cstdint.hpp>
#include <string>

// OVERVIEW
//
// This section contains fundamental time types used internall by
// libtorrent and exposed through various places in the API. The two
// basic types are ``ptime`` and ``time_duration``. The first represents
// a point in time and the second the difference between two points
// in time.
//
// The internal representation of these types is implementation defined
// and they can only be constructed via one of the construction functions
// that take a well defined time unit (seconds, minutes, etc.). They can
// only be turned into well defined time units by the accessor functions
// (total_microseconds(), etc.).
//
// .. note::
// 	In a future version of libtorrent, these types will be replaced
// 	by the standard timer types from ``std::chrono``.

namespace libtorrent
{
	TORRENT_EXTRA_EXPORT char const* time_now_string();
	std::string log_time();

	TORRENT_EXPORT ptime const& time_now();
	TORRENT_EXPORT ptime time_now_hires();

	TORRENT_EXPORT ptime min_time();
	TORRENT_EXPORT ptime max_time();

#if defined TORRENT_USE_BOOST_DATE_TIME || defined TORRENT_USE_QUERY_PERFORMANCE_TIMER

	TORRENT_EXPORT time_duration seconds(int s);
	TORRENT_EXPORT time_duration milliseconds(int s);
	TORRENT_EXPORT time_duration microsec(int s);
	TORRENT_EXPORT time_duration minutes(int s);
	TORRENT_EXPORT time_duration hours(int s);

	TORRENT_EXPORT int total_seconds(time_duration td);
	TORRENT_EXPORT int total_milliseconds(time_duration td);
	TORRENT_EXPORT boost::int64_t total_microseconds(time_duration td);

#elif TORRENT_USE_CLOCK_GETTIME || TORRENT_USE_SYSTEM_TIME || TORRENT_USE_ABSOLUTE_TIME

	// hidden
	inline int total_seconds(time_duration td)
	{ return td.diff / 1000000; }
	// hidden
	inline int total_milliseconds(time_duration td)
	{ return td.diff / 1000; }
	// hidden
	inline boost::int64_t total_microseconds(time_duration td)
	{ return td.diff; }

	// hidden
	inline time_duration microsec(boost::int64_t s)
	{ return time_duration(s); }
	// hidden
	inline time_duration milliseconds(boost::int64_t s)
	{ return time_duration(s * 1000); }
	// hidden
	inline time_duration seconds(boost::int64_t s)
	{ return time_duration(s * 1000000); }
	// hidden
	inline time_duration minutes(boost::int64_t s)
	{ return time_duration(s * 1000000 * 60); }
	// hidden
	inline time_duration hours(boost::int64_t s)
	{ return time_duration(s * 1000000 * 60 * 60); }

#endif // TORRENT_USE_CLOCK_GETTIME

}

#endif // TORRENT_TIME_HPP_INCLUDED

<|endoftext|>


<commit_before>#pragma once

#include "seq.hpp"
#include "util.hpp"
#include "value.hpp"

#include <memory>
#include <vector>

namespace imu {

  namespace ty {

    template<typename mixin = no_mixin>
    struct base_node : public mixin {

      typedef std::shared_ptr<base_node> p;

      mixin _mixin;

      virtual ~base_node()
      {}
    };

    template<typename mixin = no_mixin>
    struct basic_node : public base_node<mixin> {

      typedef std::shared_ptr<basic_node> p;
      typedef typename base_node<mixin>::p base;

      std::vector<base> _arr;

      inline basic_node()
        : _arr(32)
      {}

      inline basic_node(const p& root)
        : _arr(root->_arr)
      {}

      inline basic_node(const base& root, const base& node)
        : basic_node()
      {
        _arr[0] = root;
        _arr[1] = node;
      }

      inline basic_node(const base& child)
        : basic_node()
      {
        _arr[0] = child;
      }

      static inline base new_path(uint64_t level, const base& node) {

        base out(node);
        for(auto l = level; level != 0; level -= 5) {
          out = base(nu<basic_node>(out));
        }
        return out;
      }

      static inline p push_tail(
          uint64_t cnt
        , uint64_t level
        , const p& parent
        , const base& tail) {

        p out(nu<basic_node>(*parent));
        base insert;

        uint64_t idx = ((cnt - 1) >> level) & 0x01f;

        if (level == 5) {
          insert = tail;
        }
        else {
          auto child = parent->_arr[idx];
          if (child) {
            auto as_base = std::dynamic_pointer_cast<basic_node>(child);
            insert = push_tail(cnt, level - 5, as_base, tail);
          }
          else {
            insert = new_path(level - 5, tail);
          }
        }

        out->_arr[idx] = insert;

        return out;
      }
    };

    template<typename Value, typename mixin = no_mixin>
    struct basic_leaf : public base_node<mixin> {

      typedef std::shared_ptr<basic_leaf> p;
      typedef base_node<mixin>  base;
      typedef basic_node<mixin> node;

      std::vector<Value> _arr;

      inline basic_leaf()
      {}

      inline basic_leaf(const basic_leaf::p& a)
        : _arr(a->_arr)
      {}

      inline basic_leaf(const Value& val)
      { _arr.push_back(val); }

      inline const Value& operator[](uint64_t n) const {
        return _arr[n];
      }

      static inline typename base::p assoc(
        const typename base::p& n, uint64_t level,
        uint64_t k, const Value& v) {

        uint64_t idx = (k >> level) & 0x01f;
        if (level == 0) {
          auto leaf = std::static_pointer_cast<basic_leaf>(n);
          leaf->_arr[idx] = v;
          return leaf;
        }
        else {
          auto bn  = std::static_pointer_cast<node>(n);
          auto ret = nu<node>(bn);

          ret->_arr[idx] = assoc(bn->_arr[idx], level - 5, k, v);

          return ret;
        }
      }
    };

    template<
        typename Value = value
      , typename mixin = no_mixin
      , typename node  = basic_node<>
      , typename leaf  = basic_leaf<Value>
      >
    struct basic_vector : public mixin {

      typedef typename mixin::template semantics<basic_vector>::p p;

      typedef typename node::base base_node;
      typedef leaf leaf_type;

      typedef Value value_type;

      uint64_t _cnt;
      uint64_t _shift;

      typename node::p _root;
      typename leaf::p _tail;

      inline basic_vector()
        : _cnt(0)
        , _shift(5)
        , _root(nu<node>())
        , _tail(nu<leaf>())
      {}

      inline basic_vector(const p& v)
        : _cnt(v->_cnt)
        , _shift(v->_shift)
        , _root(v->_root)
        , _tail(nu<leaf>(v->_tail))
      {}

      inline basic_vector(const p& v, const Value& val)
        : _cnt(v->_cnt + 1)
        , _shift(v->_shift)
        , _tail(v->_tail)
      {
        if ((v->_cnt - v->tail_off()) < 32) {
          _shift = v->_shift;
          _root  = v->_root;
          _tail->_arr.push_back(val);
        }
        else {
          extend_root(v, val);
        }
      }

      template<typename T>
      static inline p from_std(const T& coll) {
        auto out = nu<basic_vector>();
        for (auto& val : coll) {
          out = nu<basic_vector>(out, val);
        }
        return out;
      }

      inline bool is_empty() const {
        return _cnt == 0;
      }

      inline uint64_t count() const {
        return _cnt;
      }

      inline const value_type& nth(uint64_t n) const {
        return (*leaf_for(n))[n & 0x01f];
      }

      template<typename T>
      inline const T& nth(uint64_t n) const {
        return value_cast<T>(nth(n));
      }

      inline const value_type& operator[](uint64_t n) const {
        return nth(n);
      }

      inline const value_type& operator()(uint64_t n) const {
        return nth(n);
      }

      template<typename S>
      inline friend bool operator== (const p& self, const S& x) {
        return seqs::equiv(seq(self), x);
      }

      template<typename S>
      inline friend bool operator== (const p& self, const std::shared_ptr<S>& x) {
        return seqs::equiv(seq(self), x);
      }

      inline uint64_t tail_off() const {
        return (_cnt < 32) ? 0 : ((_cnt - 1) >> 5) << 5;
      }

      inline const typename leaf::p leaf_for(uint64_t n) const {
        if (n >= 0 && n < _cnt) {
          if (n >= tail_off()) {
            return _tail;
          }
          typename node::base out = _root;
          for (auto level = _shift; level > 0; level -= 5) {
            auto inner = std::dynamic_pointer_cast<node>(out);
            out = inner->_arr[(n >> level) & 0x01f];
          }
          return std::dynamic_pointer_cast<leaf>(out);
        }
        throw out_of_bounds(n, _cnt);
      }

      inline void extend_root(const p& v, const value_type& val) {

        auto new_leaf = nu<leaf>(v->_tail);
        _tail = nu<leaf>(val);

        bool overflow = ((v->_cnt >> 5) > (1 << v->_shift));
        if (overflow) {
          _shift = v->_shift + 5;
          _root  = nu<node>(v->_root, node::new_path(v->_shift, new_leaf));
        }
        else {
          _root = node::push_tail(v->_cnt, _shift, v->_root, new_leaf);
        }
      }

      static inline p assoc(const p& v, uint64_t idx, const value_type& val) {
        if (0 <= idx && idx < v->_cnt) {

          auto ret = imu::nu<basic_vector>(v);

          if (v->tail_off() <= idx) {
            ret->_tail->_arr[(idx & 0x01)] = val;
          }
          else {
            auto root = leaf::assoc(ret->_root, ret->_shift, idx, val);
            ret->_root = std::static_pointer_cast<node>(root);
          }
          return ret;
        }
        else {
          return nu<basic_vector>(v, val);
        }
      }
    };

    typedef basic_vector<> vector;

    template<typename V = vector, typename mixin = no_mixin>
    struct basic_chunked_seq : public no_mixin {

      typedef std::shared_ptr<basic_chunked_seq> p;

      typedef typename V::value_type value_type;
      typedef typename V::leaf_type  leaf_type;

      mixin _mixin;

      typename V::p _vec;
      uint64_t      _idx;
      uint64_t      _off;

      typename leaf_type::p _leaf;

      inline basic_chunked_seq(const typename V::p& v, uint64_t i, uint64_t o)
        : _vec(v)
        , _idx(i)
        , _off(o)
        , _leaf(v->leaf_for(_idx))
      {}

      inline bool is_empty() const {
        return (_off >= _leaf->_arr.size());
      }

      template<typename T>
      inline const T& first() const {
        return value_cast<T>((*_leaf)[_off]);
      }

      inline const value_type& first() const {
        return (*_leaf)[_off];
      };

      inline p rest() const {
        if (!is_empty()) {
          return nu<basic_chunked_seq>(_vec, _idx, _off + 1);
        }
        return p();
      }

      template<typename S>
      inline friend bool operator== (const p& self, const S& x) {
        return seqs::equiv(self, x);
      }

      template<typename S>
      inline friend bool operator== (const p& self, const std::shared_ptr<S>& x) {
        return seqs::equiv(self, x);
      }
    };

    typedef basic_chunked_seq<> chunked_seq;
  }

  inline ty::vector::p vector() {
    return nu<ty::vector>();
  }

  template<typename Arg>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x) {
    return conj(v, x);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x, Args... args) {
    return vector(conj(v, x), args...);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const Arg& x, Args... args) {
    return vector(vector(), x, args...);
  }

  template<typename T>
  inline auto vector(const T& coll)
    -> decltype(std::begin(coll), std::end(coll), ty::list::p()) {
    return ty::vector::from_std(coll);
  }

  template<typename T>
  inline ty::vector::p vector(std::initializer_list<T> l) {
    return ty::vector::from_std(l);
  }

  // @cond HIDE
  template<typename... TS>
  inline decltype(auto) seq(
    const std::shared_ptr<ty::basic_vector<TS...>>& v) {

    typedef typename ty::basic_vector<TS...> V;
    typedef typename ty::basic_chunked_seq<> S;

    if (!v || v->is_empty()) {
      return typename S::p();
    }
    return nu<S>(v, 0, 0);
  }

  template<typename... TS>
  inline decltype(auto) seq(ty::basic_vector<TS...>* const & v) {

    typedef typename ty::basic_vector<TS...>  V;
    typedef typename ty::basic_chunked_seq<V> S;

    if (!v || v->is_empty()) {
      return typename S::p();
    }
    return nu<S>(v, 0, 0);
  }

  template<typename T, typename... TS>
  inline ty::vector::p conj(
    const typename ty::basic_vector<TS...>::p& v, const T& x) {

    return nu<ty::vector>(v, x);
  }
  // @endcond
}
<commit_msg>Fix conj on vector<commit_after>#pragma once

#include "seq.hpp"
#include "util.hpp"
#include "value.hpp"

#include <memory>
#include <vector>

namespace imu {

  namespace ty {

    template<typename mixin = no_mixin>
    struct base_node : public mixin {

      typedef std::shared_ptr<base_node> p;

      mixin _mixin;

      virtual ~base_node()
      {}
    };

    template<typename mixin = no_mixin>
    struct basic_node : public base_node<mixin> {

      typedef std::shared_ptr<basic_node> p;
      typedef typename base_node<mixin>::p base;

      std::vector<base> _arr;

      inline basic_node()
        : _arr(32)
      {}

      inline basic_node(const p& root)
        : _arr(root->_arr)
      {}

      inline basic_node(const base& root, const base& node)
        : basic_node()
      {
        _arr[0] = root;
        _arr[1] = node;
      }

      inline basic_node(const base& child)
        : basic_node()
      {
        _arr[0] = child;
      }

      static inline base new_path(uint64_t level, const base& node) {

        base out(node);
        for(auto l = level; level != 0; level -= 5) {
          out = base(nu<basic_node>(out));
        }
        return out;
      }

      static inline p push_tail(
          uint64_t cnt
        , uint64_t level
        , const p& parent
        , const base& tail) {

        p out(nu<basic_node>(*parent));
        base insert;

        uint64_t idx = ((cnt - 1) >> level) & 0x01f;

        if (level == 5) {
          insert = tail;
        }
        else {
          auto child = parent->_arr[idx];
          if (child) {
            auto as_base = std::dynamic_pointer_cast<basic_node>(child);
            insert = push_tail(cnt, level - 5, as_base, tail);
          }
          else {
            insert = new_path(level - 5, tail);
          }
        }

        out->_arr[idx] = insert;

        return out;
      }
    };

    template<typename Value, typename mixin = no_mixin>
    struct basic_leaf : public base_node<mixin> {

      typedef std::shared_ptr<basic_leaf> p;
      typedef base_node<mixin>  base;
      typedef basic_node<mixin> node;

      std::vector<Value> _arr;

      inline basic_leaf()
      {}

      inline basic_leaf(const basic_leaf::p& a)
        : _arr(a->_arr)
      {}

      inline basic_leaf(const Value& val)
      { _arr.push_back(val); }

      inline const Value& operator[](uint64_t n) const {
        return _arr[n];
      }

      static inline typename base::p assoc(
        const typename base::p& n, uint64_t level,
        uint64_t k, const Value& v) {

        uint64_t idx = (k >> level) & 0x01f;
        if (level == 0) {
          auto leaf = std::static_pointer_cast<basic_leaf>(n);
          leaf->_arr[idx] = v;
          return leaf;
        }
        else {
          auto bn  = std::static_pointer_cast<node>(n);
          auto ret = nu<node>(bn);

          ret->_arr[idx] = assoc(bn->_arr[idx], level - 5, k, v);

          return ret;
        }
      }
    };

    struct vector_tag {};

    template<
        typename Value = value
      , typename mixin = no_mixin
      , typename node  = basic_node<>
      , typename leaf  = basic_leaf<Value>
      >
    struct basic_vector : public mixin, vector_tag {

      typedef typename mixin::template semantics<basic_vector>::p p;

      typedef typename node::base base_node;
      typedef leaf leaf_type;

      typedef Value value_type;

      uint64_t _cnt;
      uint64_t _shift;

      typename node::p _root;
      typename leaf::p _tail;

      inline basic_vector()
        : _cnt(0)
        , _shift(5)
        , _root(nu<node>())
        , _tail(nu<leaf>())
      {}

      inline basic_vector(const p& v)
        : _cnt(v->_cnt)
        , _shift(v->_shift)
        , _root(v->_root)
        , _tail(nu<leaf>(v->_tail))
      {}

      inline basic_vector(const p& v, const Value& val)
        : _cnt(v->_cnt + 1)
        , _shift(v->_shift)
        , _tail(v->_tail)
      {
        if ((v->_cnt - v->tail_off()) < 32) {
          _shift = v->_shift;
          _root  = v->_root;
          _tail->_arr.push_back(val);
        }
        else {
          extend_root(v, val);
        }
      }

      template<typename T>
      static inline p from_std(const T& coll) {
        auto out = nu<basic_vector>();
        for (auto& val : coll) {
          out = nu<basic_vector>(out, val);
        }
        return out;
      }

      inline bool is_empty() const {
        return _cnt == 0;
      }

      inline uint64_t count() const {
        return _cnt;
      }

      inline const value_type& nth(uint64_t n) const {
        return (*leaf_for(n))[n & 0x01f];
      }

      template<typename T>
      inline const T& nth(uint64_t n) const {
        return value_cast<T>(nth(n));
      }

      inline const value_type& operator[](uint64_t n) const {
        return nth(n);
      }

      inline const value_type& operator()(uint64_t n) const {
        return nth(n);
      }

      template<typename S>
      inline friend bool operator== (const p& self, const S& x) {
        return seqs::equiv(seq(self), x);
      }

      template<typename S>
      inline friend bool operator== (const p& self, const std::shared_ptr<S>& x) {
        return seqs::equiv(seq(self), x);
      }

      inline uint64_t tail_off() const {
        return (_cnt < 32) ? 0 : ((_cnt - 1) >> 5) << 5;
      }

      inline const typename leaf::p leaf_for(uint64_t n) const {
        if (n >= 0 && n < _cnt) {
          if (n >= tail_off()) {
            return _tail;
          }
          typename node::base out = _root;
          for (auto level = _shift; level > 0; level -= 5) {
            auto inner = std::dynamic_pointer_cast<node>(out);
            out = inner->_arr[(n >> level) & 0x01f];
          }
          return std::dynamic_pointer_cast<leaf>(out);
        }
        throw out_of_bounds(n, _cnt);
      }

      inline void extend_root(const p& v, const value_type& val) {

        auto new_leaf = nu<leaf>(v->_tail);
        _tail = nu<leaf>(val);

        bool overflow = ((v->_cnt >> 5) > (1 << v->_shift));
        if (overflow) {
          _shift = v->_shift + 5;
          _root  = nu<node>(v->_root, node::new_path(v->_shift, new_leaf));
        }
        else {
          _root = node::push_tail(v->_cnt, _shift, v->_root, new_leaf);
        }
      }

      static inline p assoc(const p& v, uint64_t idx, const value_type& val) {
        if (0 <= idx && idx < v->_cnt) {

          auto ret = imu::nu<basic_vector>(v);

          if (v->tail_off() <= idx) {
            ret->_tail->_arr[(idx & 0x01)] = val;
          }
          else {
            auto root = leaf::assoc(ret->_root, ret->_shift, idx, val);
            ret->_root = std::static_pointer_cast<node>(root);
          }
          return ret;
        }
        else {
          return nu<basic_vector>(v, val);
        }
      }
    };

    typedef basic_vector<> vector;

    template<typename V = vector, typename mixin = no_mixin>
    struct basic_chunked_seq : public no_mixin {

      typedef std::shared_ptr<basic_chunked_seq> p;

      typedef typename V::value_type value_type;
      typedef typename V::leaf_type  leaf_type;

      mixin _mixin;

      typename V::p _vec;
      uint64_t      _idx;
      uint64_t      _off;

      typename leaf_type::p _leaf;

      inline basic_chunked_seq(const typename V::p& v, uint64_t i, uint64_t o)
        : _vec(v)
        , _idx(i)
        , _off(o)
        , _leaf(v->leaf_for(_idx))
      {}

      inline bool is_empty() const {
        return (_off >= _leaf->_arr.size());
      }

      template<typename T>
      inline const T& first() const {
        return value_cast<T>((*_leaf)[_off]);
      }

      inline const value_type& first() const {
        return (*_leaf)[_off];
      };

      inline p rest() const {
        if (!is_empty()) {
          return nu<basic_chunked_seq>(_vec, _idx, _off + 1);
        }
        return p();
      }

      template<typename S>
      inline friend bool operator== (const p& self, const S& x) {
        return seqs::equiv(self, x);
      }

      template<typename S>
      inline friend bool operator== (const p& self, const std::shared_ptr<S>& x) {
        return seqs::equiv(self, x);
      }
    };

    typedef basic_chunked_seq<> chunked_seq;
  }

  inline ty::vector::p vector() {
    return nu<ty::vector>();
  }

  template<typename Arg>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x) {
    return conj(v, x);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const ty::vector::p& v, const Arg& x, Args... args) {
    return vector(conj(v, x), args...);
  }

  template<typename Arg, typename... Args>
  inline ty::vector::p vector(const Arg& x, Args... args) {
    return vector(vector(), x, args...);
  }

  template<typename T>
  inline auto vector(const T& coll)
    -> decltype(std::begin(coll), std::end(coll), ty::list::p()) {
    return ty::vector::from_std(coll);
  }

  template<typename T>
  inline ty::vector::p vector(std::initializer_list<T> l) {
    return ty::vector::from_std(l);
  }

  // @cond HIDE
  template<typename... TS>
  inline decltype(auto) seq(
    const std::shared_ptr<ty::basic_vector<TS...>>& v) {

    typedef typename ty::basic_vector<TS...> V;
    typedef typename ty::basic_chunked_seq<> S;

    if (!v || v->is_empty()) {
      return typename S::p();
    }
    return nu<S>(v, 0, 0);
  }

  template<typename... TS>
  inline decltype(auto) seq(ty::basic_vector<TS...>* const & v) {

    typedef typename ty::basic_vector<TS...>  V;
    typedef typename ty::basic_chunked_seq<V> S;

    if (!v || v->is_empty()) {
      return typename S::p();
    }
    return nu<S>(v, 0, 0);
  }

  template<typename V, typename T>
  inline typename std::enable_if<
    std::is_base_of<
      ty::vector_tag
      , typename semantics::real_type<V>::type
      >::value,
    typename semantics::real_type<V>::type::p
    >::type
  conj(const V& v, const T& x) {
    typedef typename semantics::real_type<V>::type type;
    return nu<type>(v, x);
  }
  // @endcond
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Implementation of a Restricted Boltzmann Machine
 */

#pragma once

#include "cpp_utils/assert.hpp"     //Assertions
#include "cpp_utils/stop_watch.hpp" //Performance counter

#include "etl/etl.hpp"

#include "standard_rbm.hpp"
#include "layer_traits.hpp"

#include "util/converter.hpp" //converter

namespace dll {

/*!
 * \brief Standard version of Restricted Boltzmann Machine
 *
 * This follows the definition of a RBM by Geoffrey Hinton.
 */
template <typename Desc>
struct rbm final : public standard_rbm<rbm<Desc>, Desc> {
    using desc      = Desc;                          ///< The layer descriptor
    using weight    = typename desc::weight;         ///< The weight type
    using this_type = rbm<desc>;                     ///< The type of this layer
    using base_type = standard_rbm<this_type, desc>; ///< The base type

    using input_t      = typename rbm_base_traits<this_type>::input_t;
    using output_t     = typename rbm_base_traits<this_type>::output_t;
    using input_one_t  = typename rbm_base_traits<this_type>::input_one_t;
    using output_one_t = typename rbm_base_traits<this_type>::output_one_t;

    static constexpr const std::size_t num_visible = desc::num_visible; ///< The number of visible units
    static constexpr const std::size_t num_hidden  = desc::num_hidden;  ///< The number of hidden units

    static constexpr const unit_type visible_unit = desc::visible_unit; ///< The type of visible units
    static constexpr const unit_type hidden_unit  = desc::hidden_unit;  ///< The type of hidden units

    static constexpr bool dbn_only = layer_traits<this_type>::is_dbn_only();

    template <std::size_t B>
    using input_batch_t = etl::fast_dyn_matrix<weight, B, num_visible>;

    using w_type = etl::fast_matrix<weight, num_visible, num_hidden>; ///< The type used to store weights
    using b_type = etl::fast_vector<weight, num_hidden>;              ///< The type used to store hidden biases
    using c_type = etl::fast_vector<weight, num_visible>;             ///< The type used to store visible biases

    //Weights and biases
    w_type w; //!< Weights
    b_type b; //!< Hidden biases
    c_type c; //!< Visible biases

    //Backup weights and biases
    std::unique_ptr<w_type> bak_w; //!< Backup Weights
    std::unique_ptr<b_type> bak_b; //!< Backup Hidden biases
    std::unique_ptr<c_type> bak_c; //!< Backup Visible biases

    //Reconstruction data
    conditional_fast_matrix_t<!dbn_only, weight, num_visible> v1; //!< State of the visible units

    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h1_a; //!< Activation probabilities of hidden units after first CD-step
    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h1_s; //!< Sampled value of hidden units after first CD-step

    conditional_fast_matrix_t<!dbn_only, weight, num_visible> v2_a; //!< Activation probabilities of visible units after first CD-step
    conditional_fast_matrix_t<!dbn_only, weight, num_visible> v2_s; //!< Sampled value of visible units after first CD-step

    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h2_a; //!< Activation probabilities of hidden units after last CD-step
    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h2_s; //!< Sampled value of hidden units after last CD-step

    //No copying
    rbm(const rbm& rbm) = delete;
    rbm& operator=(const rbm& rbm) = delete;

    //No moving
    rbm(rbm&& rbm) = delete;
    rbm& operator=(rbm&& rbm) = delete;

    /*!
     * \brief Initialize a RBM with basic weights.
     *
     * The weights are initialized from a normal distribution of
     * zero-mean and 0.1 variance.
     */
    rbm()
            : standard_rbm<rbm<Desc>, Desc>(), b(0.0), c(0.0) {
        //Initialize the weights with a zero-mean and unit variance Gaussian distribution
        w = etl::normal_generator<weight>() * 0.1;
    }

    static constexpr std::size_t input_size() noexcept {
        return num_visible;
    }

    static constexpr std::size_t output_size() noexcept {
        return num_hidden;
    }

    static constexpr std::size_t parameters() noexcept {
        return num_visible * num_hidden;
    }

    static std::string to_short_string() {
        return "RBM: " + std::to_string(num_visible) + "(" + to_string(visible_unit) + ") -> " + std::to_string(num_hidden) + "(" + to_string(hidden_unit) + ")";
    }

    template<typename DRBM>
    static void dyn_init(DRBM& dyn){
        dyn.init_layer(num_visible, num_hidden);
        dyn.batch_size  = layer_traits<this_type>::batch_size();
    }

    void prepare_input(input_one_t&) const {
        // Nothing to do
    }

    template <std::size_t B>
    auto prepare_input_batch(){
        return etl::fast_dyn_matrix<weight, B, num_visible>();
    }

    template <std::size_t B>
    auto prepare_output_batch(){
        return etl::fast_dyn_matrix<weight, B, num_hidden>();
    }
};

/*!
 * \brief Simple traits to pass information around from the real
 * class to the CRTP class.
 */
template <typename Desc>
struct rbm_base_traits<rbm<Desc>> {
    using desc      = Desc;
    using weight    = typename desc::weight;

    using input_one_t  = etl::dyn_vector<weight>;
    using output_one_t = etl::dyn_vector<weight>;
    using input_t      = std::vector<input_one_t>;
    using output_t     = std::vector<output_one_t>;
};

//Allow odr-use of the constexpr static members

template <typename Desc>
const std::size_t rbm<Desc>::num_visible;

template <typename Desc>
const std::size_t rbm<Desc>::num_hidden;

} //end of dll namespace
<commit_msg>Fix prepare_input<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

/*!
 * \file
 * \brief Implementation of a Restricted Boltzmann Machine
 */

#pragma once

#include "cpp_utils/assert.hpp"     //Assertions
#include "cpp_utils/stop_watch.hpp" //Performance counter

#include "etl/etl.hpp"

#include "standard_rbm.hpp"
#include "layer_traits.hpp"

#include "util/converter.hpp" //converter

namespace dll {

/*!
 * \brief Standard version of Restricted Boltzmann Machine
 *
 * This follows the definition of a RBM by Geoffrey Hinton.
 */
template <typename Desc>
struct rbm final : public standard_rbm<rbm<Desc>, Desc> {
    using desc      = Desc;                          ///< The layer descriptor
    using weight    = typename desc::weight;         ///< The weight type
    using this_type = rbm<desc>;                     ///< The type of this layer
    using base_type = standard_rbm<this_type, desc>; ///< The base type

    using input_t      = typename rbm_base_traits<this_type>::input_t;
    using output_t     = typename rbm_base_traits<this_type>::output_t;
    using input_one_t  = typename rbm_base_traits<this_type>::input_one_t;
    using output_one_t = typename rbm_base_traits<this_type>::output_one_t;

    static constexpr const std::size_t num_visible = desc::num_visible; ///< The number of visible units
    static constexpr const std::size_t num_hidden  = desc::num_hidden;  ///< The number of hidden units

    static constexpr const unit_type visible_unit = desc::visible_unit; ///< The type of visible units
    static constexpr const unit_type hidden_unit  = desc::hidden_unit;  ///< The type of hidden units

    static constexpr bool dbn_only = layer_traits<this_type>::is_dbn_only();

    template <std::size_t B>
    using input_batch_t = etl::fast_dyn_matrix<weight, B, num_visible>;

    using w_type = etl::fast_matrix<weight, num_visible, num_hidden>; ///< The type used to store weights
    using b_type = etl::fast_vector<weight, num_hidden>;              ///< The type used to store hidden biases
    using c_type = etl::fast_vector<weight, num_visible>;             ///< The type used to store visible biases

    //Weights and biases
    w_type w; //!< Weights
    b_type b; //!< Hidden biases
    c_type c; //!< Visible biases

    //Backup weights and biases
    std::unique_ptr<w_type> bak_w; //!< Backup Weights
    std::unique_ptr<b_type> bak_b; //!< Backup Hidden biases
    std::unique_ptr<c_type> bak_c; //!< Backup Visible biases

    //Reconstruction data
    conditional_fast_matrix_t<!dbn_only, weight, num_visible> v1; //!< State of the visible units

    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h1_a; //!< Activation probabilities of hidden units after first CD-step
    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h1_s; //!< Sampled value of hidden units after first CD-step

    conditional_fast_matrix_t<!dbn_only, weight, num_visible> v2_a; //!< Activation probabilities of visible units after first CD-step
    conditional_fast_matrix_t<!dbn_only, weight, num_visible> v2_s; //!< Sampled value of visible units after first CD-step

    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h2_a; //!< Activation probabilities of hidden units after last CD-step
    conditional_fast_matrix_t<!dbn_only, weight, num_hidden> h2_s; //!< Sampled value of hidden units after last CD-step

    //No copying
    rbm(const rbm& rbm) = delete;
    rbm& operator=(const rbm& rbm) = delete;

    //No moving
    rbm(rbm&& rbm) = delete;
    rbm& operator=(rbm&& rbm) = delete;

    /*!
     * \brief Initialize a RBM with basic weights.
     *
     * The weights are initialized from a normal distribution of
     * zero-mean and 0.1 variance.
     */
    rbm()
            : standard_rbm<rbm<Desc>, Desc>(), b(0.0), c(0.0) {
        //Initialize the weights with a zero-mean and unit variance Gaussian distribution
        w = etl::normal_generator<weight>() * 0.1;
    }

    static constexpr std::size_t input_size() noexcept {
        return num_visible;
    }

    static constexpr std::size_t output_size() noexcept {
        return num_hidden;
    }

    static constexpr std::size_t parameters() noexcept {
        return num_visible * num_hidden;
    }

    static std::string to_short_string() {
        return "RBM: " + std::to_string(num_visible) + "(" + to_string(visible_unit) + ") -> " + std::to_string(num_hidden) + "(" + to_string(hidden_unit) + ")";
    }

    template<typename DRBM>
    static void dyn_init(DRBM& dyn){
        dyn.init_layer(num_visible, num_hidden);
        dyn.batch_size  = layer_traits<this_type>::batch_size();
    }

    void prepare_input(input_one_t& input) const {
        // Need to initialize the dimensions of the matrix
        input = input_one_t(num_visible);
    }

    template <std::size_t B>
    auto prepare_input_batch(){
        return etl::fast_dyn_matrix<weight, B, num_visible>();
    }

    template <std::size_t B>
    auto prepare_output_batch(){
        return etl::fast_dyn_matrix<weight, B, num_hidden>();
    }
};

/*!
 * \brief Simple traits to pass information around from the real
 * class to the CRTP class.
 */
template <typename Desc>
struct rbm_base_traits<rbm<Desc>> {
    using desc      = Desc;
    using weight    = typename desc::weight;

    using input_one_t  = etl::dyn_vector<weight>;
    using output_one_t = etl::dyn_vector<weight>;
    using input_t      = std::vector<input_one_t>;
    using output_t     = std::vector<output_one_t>;
};

//Allow odr-use of the constexpr static members

template <typename Desc>
const std::size_t rbm<Desc>::num_visible;

template <typename Desc>
const std::size_t rbm<Desc>::num_hidden;

} //end of dll namespace
<|endoftext|>


<commit_before>/*

PICCANTE
The hottest HDR imaging library!
http://vcg.isti.cnr.it/piccante

Copyright (C) 2014
Visual Computing Laboratory - ISTI CNR
http://vcg.isti.cnr.it
First author: Francesco Banterle

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/.

*/

#ifndef PIC_UTIL_coeffNOMIAL_HPP
#define PIC_UTIL_coeffNOMIAL_HPP

#include <vector>

#include "../base.hpp"

#ifndef PIC_DISABLE_EIGEN
    #ifndef PIC_EIGEN_NOT_BUNDLED
        #include "../externals/Eigen/QR"
        #include "../externals/Eigen/Eigenvalues"
    #else
        #include <Eigen/QR>
    #endif
#endif

namespace pic {

class Polynomial
{
public:
    std::vector<float> coeff;
    bool  all_coeff_positive;

    /**
     * @brief Polynomial
     */
    Polynomial()
    {
        all_coeff_positive = true;
    }

    /**
     * @brief Polynomial
     * @param nCoeff
     */
    Polynomial(int nCoeff)
    {
        for(int i = 0; i < nCoeff; i++) {
            coeff.push_back(0.0f);
        }
        all_coeff_positive = true;
    }

    /**
     * @brief coeffnomial
     * @param coeff
     * @param nCoeff
     */
    Polynomial(float *coeff, int nCoeff)
    {
        if(nCoeff < 1 || coeff == NULL) {
            return;
        }

        this->coeff.assign(coeff, coeff + nCoeff);

        computeAllCoeffPositive();
    }

    ~Polynomial()
    {

    }

    /**
     * @brief computeAllCoeffPositive
     */
    void computeAllCoeffPositive()
    {
        int counter = 0;
        for (const float &c : coeff) {
            if(c < 0.0f) {
                counter++;
            }
        }

        all_coeff_positive = counter < 1;
    }

    /**
     * @brief print
     */
    void print()
    {
        printf("%s\n", toString().c_str());
    }

    std::string toString()
    {
        std::string ret = "";
        if(coeff.empty()) {
            return ret;
        }
        int nCoeff = coeff.size();

        if(nCoeff > 1) {

            std::string sep = "+ ";
            if(coeff[1] < 0.0f) {
                sep = " ";
            }

            ret = fromNumberToString(coeff[0]) + sep;

            for(int i = 1; i < (nCoeff - 1); i++) {

                if(coeff[i + 1] > 0.0f) {
                    sep = "+ ";
                } else {
                    sep = " ";
                }

                ret += fromNumberToString(coeff[i]) + " * x^" + fromNumberToString(i) + sep;
            }

            ret += fromNumberToString(coeff[nCoeff - 1]) + " * x^" + fromNumberToString(nCoeff - 1);
        } else {
            ret = fromNumberToString(coeff[0]);
        }
        return ret;
    }

    /**
     * @brief getArray
     * @return
     */
    float *getArray(float *ret)
    {
        if(ret == NULL) {
            ret = new float[coeff.size()];
        }

        for(int i = 0; i < coeff.size(); i++) {
            ret[i] = coeff[i];
        }
        return ret;
    }

    /**
     * @brief eval
     * @param x
     * @return
     */
    float eval(float x)
    {
        float val = 0.f;
        float M = 1.f;
        for (const float &c : coeff) {
            val += c * M;
            M *= x;
        }
        return val;
    }

    /**
     * @brief dEval
     * @param t
     * @return
     */
    float dEval(float x)
    {
        int nCoeff = coeff.size();

        if(nCoeff < 2) {
            return 0.0f;
        }

        float ret = coeff[nCoeff - 1] * float(nCoeff - 1);

        for(int i = (nCoeff - 2); i > 0 ; i--) {
            ret = (ret * x) + coeff[i] * float(i);
        }
        return ret;
    }

    /**
     * @brief fit
     * @param x
     * @param y
     * @param n
     */
    void fit(std::vector<float> &x, std::vector<float> &y, int n)
    {
#ifndef PIC_DISABLE_EIGEN
        if(n < 1 || (x.size() != y.size())) {
            return;
        }

        coeff.clear();

        int np1 = n + 1;

        int s = int(x.size());
        Eigen::MatrixXf A(s, np1);
        Eigen::VectorXf b(s);

        for(int i = 0; i < s; i++) {
            b(i) = y[i];
            A(i, n) = 1.0f;
        }

        for(int j = (n - 1); j >= 0; j--) {
            for(int i = 0; i < s; i++) {
                A(i, j) = x[i] * A(i, j + 1);
            }
        }

        Eigen::VectorXf _x = A.colPivHouseholderQr().solve(b);

        for(int i = n; i >= 0; i--) {
            coeff.push_back(_x(i));
        }
#endif
    }

    /**
     * @brief normalForm
     */
    void normalForm()
    {
        int last = coeff.size() - 1;
        if(fabsf(coeff[last]) > 0.0f) {
            for(int i = 0; i < last; i++) {
                coeff[i] /= coeff[last];
            }

            coeff[last] = 1.0f;
        }
    }

    /**
     * @brief horner
     * @param d
     * @param remainder
     * @return
     */
    Polynomial horner(float d, float &remainder)
    {
        int nCoeff = coeff.size();
        Polynomial p(nCoeff - 1);

        p.coeff[nCoeff - 2] = coeff[nCoeff - 1];

        for(int i = (nCoeff - 3); i >= 0 ; i--) {
            p.coeff[i] = (p.coeff[i + 1] * d + coeff[i + 1]);
        }

        p.computeAllCoeffPositive();

        remainder = coeff[0] + p.coeff[0] * d;

        return p;
    }

    /**
     * @brief getRoots
     * @param x
     * @return
     */
    bool getRoots(float *x)
    {
        int nCoeff = coeff.size();

        if(nCoeff < 2) {
            return false;
        }

        if(nCoeff == 2) {
            //this coefficient may be not positive
            if(coeff[1] > 0.0f) {
                x[0] = -coeff[0] / coeff[1];
                return true;
            } else {
                return false;
            }
        }

        if(nCoeff == 3) {
            //these coefficients may be not positive
            return getSecondOrderRoots(coeff[2], coeff[1], coeff[0], &x[0], &x[1]);
        }

        if(all_coeff_positive) {
            return false;
        }

        float max_coeff0 = -1.0f;

        for(int i = 1; i < coeff.size(); i++) {
            float tmp = fabsf(coeff[i]);
            if(tmp > max_coeff0) {
                max_coeff0 = tmp;
            }
        }

        float tmp = fabsf(coeff[0]);
        float max_coeff;
        if(max_coeff0 < tmp) {
            max_coeff = tmp;
        } else {
            max_coeff = max_coeff0;
        }

        float lower_bound = fabsf(coeff[0]) / (fabsf(coeff[0]) + max_coeff0);

#ifdef PIC_DEBUG
        float upper_bound = 1.0f + max_coeff / fabsf(coeff[0]);
        printf("Upper bound: %f\n", upper_bound);
        printf("Lower bound: %f\n", lower_bound);
#endif

        float x_p = lower_bound;
        float x_n;
        bool notConverged = true;
        int counter = 0;
        float E_x_p;
        while(notConverged) {
            E_x_p = eval(x_p);
            x_n = x_p - E_x_p / dEval(x_p);
            x_p = x_n;
            counter++;

            notConverged = (fabsf(E_x_p) > 1e-4f) && (counter < 200);
        }

        if(counter == 200) {
            return false;
        } else {
            *x = x_n;
            return true;
        }
    }

    /**
     * @brief getAllRoots
     * @param x
     * @return
     */
    bool getAllRoots(float *x)
    {
        for(int i = 0; i < coeff.size() - 1; i++) {
            x[i] = FLT_MAX;
        }

        bool bOut = getRoots(&x[0]);

        if(!bOut) {
            return false;
        }

        float r;
        Polynomial p = horner(x[0], r);
        p.normalForm();

        int nCoeff = coeff.size();
        for(int i = 1; i < (nCoeff - 2); i++) {
            p.print();
            bool bOut = p.getRoots(&x[i]);

            if(!bOut) {
                return true;
            }

            p = p.horner(x[i], r);
            p.normalForm();
        }

        return true;
    }

    /**
     * @brief getQuarticRoots --> MANDATORY p[0] == 1.0
     * @param p
     * @param x
     * @return
     */
    static bool getQuarticRoots(float *p, float *x)
    {
#ifndef PIC_DISABLE_EIGEN
        Eigen::Matrix4f m;

        m << -p[1], -p[2], -p[3], -p[4],
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f;

        Eigen::EigenSolver<Eigen::Matrix4f> es(m);
        Eigen::Vector4cf e = es.eigenvalues();

        bool bOut = false;
        if(fabsf(e(0).imag()) < 1e-6f) {
            x[0] = e(0).real();
            bOut = true;
        }

        if(fabsf(e(1).imag()) < 1e-6f) {
            x[1] = e(1).real();
            bOut = true;
        }

        if(fabsf(e(2).imag()) < 1e-6f) {
            x[2] = e(2).real();
            bOut = true;
        }

        if(fabsf(e(3).imag()) < 1e-6f) {
            x[3] = e(3).real();
            bOut = true;
        }

        return bOut;
#else
        return true;
#endif
    }

    //Solver for second order equations, ax^2 + b x + c = 0
    static bool getSecondOrderRoots(float a, float b, float c, float *x0, float *x1)
    {
        float delta = b * b - 4.0f * a * c;

        if(delta >= 0.0f) {
            float dnum = 2.0f * a;
            delta = sqrtf(delta);
            *x0 = (-b + delta) / dnum;
            *x1 = (-b - delta) / dnum;
            return true;
        } else {
            return false;
        }
    }

    //Solver for second order equations, ax^2 + b x + c = 0, when b is even
    static bool getSecondOrderRootsS(float a, float b, float c, float *x0, float *x1)
    {
        float delta = b * b - a * c;
        if(delta >= 0.0f) {
            delta = sqrtf(delta);
            *x0 = (-b + delta) / a;
            *x1 = (-b - delta) / a;
            return true;
        } else {
            return false;
        }
    }

};

} // end namespace pic

#endif //PIC_UTIL_coeffNOMIAL_HPP
<commit_msg>Update include/util/polynomial.hpp<commit_after>/*

PICCANTE
The hottest HDR imaging library!
http://vcg.isti.cnr.it/piccante

Copyright (C) 2014
Visual Computing Laboratory - ISTI CNR
http://vcg.isti.cnr.it
First author: Francesco Banterle

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/.

*/

#ifndef PIC_UTIL_coeffNOMIAL_HPP
#define PIC_UTIL_coeffNOMIAL_HPP

#include <vector>

#include "../base.hpp"

#ifndef PIC_DISABLE_EIGEN
    #ifndef PIC_EIGEN_NOT_BUNDLED
        #include "../externals/Eigen/QR"
        #include "../externals/Eigen/Eigenvalues"
    #else
        #include <Eigen/QR>
    #endif
#endif

namespace pic {

class Polynomial
{
public:
    std::vector<float> coeff;
    bool  all_coeff_positive;

    /**
     * @brief Polynomial
     */
    Polynomial()
    {
        all_coeff_positive = true;
    }

    /**
     * @brief Polynomial
     * @param nCoeff
     */
    Polynomial(int nCoeff)
    {
        for(int i = 0; i < nCoeff; i++) {
            coeff.push_back(0.0f);
        }
        all_coeff_positive = true;
    }

    /**
     * @brief coeffnomial
     * @param coeff
     * @param nCoeff
     */
    Polynomial(float *coeff, int nCoeff)
    {
        if(nCoeff < 1 || coeff == NULL) {
            return;
        }

        this->coeff.assign(coeff, coeff + nCoeff);

        computeAllCoeffPositive();
    }

    ~Polynomial()
    {

    }

    /**
     * @brief computeAllCoeffPositive
     */
    void computeAllCoeffPositive()
    {
        int counter = 0;
        for (const float &c : coeff) {
            if(c < 0.0f) {
                counter++;
            }
        }

        all_coeff_positive = counter < 1;
    }

    /**
     * @brief print
     */
    void print()
    {
        printf("%s\n", toString().c_str());
    }

    std::string toString()
    {
        std::string ret = "";
        if(coeff.empty()) {
            return ret;
        }
        int nCoeff = coeff.size();

        if(nCoeff > 1) {

            std::string sep = "+ ";
            if(coeff[1] < 0.0f) {
                sep = " ";
            }

            ret = fromNumberToString(coeff[0]) + sep;

            for(int i = 1; i < (nCoeff - 1); i++) {

                if(coeff[i + 1] > 0.0f) {
                    sep = "+ ";
                } else {
                    sep = " ";
                }

                ret += fromNumberToString(coeff[i]) + " * x^" + fromNumberToString(i) + sep;
            }

            ret += fromNumberToString(coeff[nCoeff - 1]) + " * x^" + fromNumberToString(nCoeff - 1);
        } else {
            ret = fromNumberToString(coeff[0]);
        }
        return ret;
    }

    /**
     * @brief getArray
     * @return
     */
    float *getArray(float *ret)
    {
        if(ret == NULL) {
            ret = new float[coeff.size()];
        }

        for(int i = 0; i < coeff.size(); i++) {
            ret[i] = coeff[i];
        }
        return ret;
    }

    /**
     * @brief eval
     * @param x
     * @return
     */
    float eval(float x)
    {
        float val = 0.f;
        float M = 1.f;
        for (const float &c : coeff) {
            val += c * M;
            M *= x;
        }
        return val;
    }

    /**
     * @brief dEval
     * @param t
     * @return
     */
    float dEval(float x)
    {
        int nCoeff = coeff.size();

        if(nCoeff < 2) {
            return 0.0f;
        }

        float ret = coeff[nCoeff - 1] * float(nCoeff - 1);

        for(int i = (nCoeff - 2); i > 0 ; i--) {
            ret = (ret * x) + coeff[i] * float(i);
        }
        return ret;
    }

    /**
     * @brief fit
     * @param x
     * @param y
     * @param n
     */
    void fit(std::vector<float> &x, std::vector<float> &y, int n)
    {
#ifndef PIC_DISABLE_EIGEN
        if(n < 1 || (x.size() != y.size())) {
            return;
        }

        coeff.clear();

        int np1 = n + 1;

        int s = int(x.size());
        Eigen::MatrixXf A(s, np1);
        Eigen::VectorXf b(s);

        for(int i = 0; i < s; i++) {
            b(i) = y[i];
            A(i, n) = 1.0f;
        }

        for(int j = (n - 1); j >= 0; j--) {
            for(int i = 0; i < s; i++) {
                A(i, j) = x[i] * A(i, j + 1);
            }
        }

        Eigen::VectorXf _x = A.colPivHouseholderQr().solve(b);

        for(int i = n; i >= 0; i--) {
            coeff.push_back(_x(i));
        }
#endif
    }

    /**
     * @brief normalForm
     */
    void normalForm()
    {
        int last = coeff.size() - 1;
        if(fabsf(coeff[last]) > 0.0f) {
            for(int i = 0; i < last; i++) {
                coeff[i] /= coeff[last];
            }

            coeff[last] = 1.0f;
        }
    }

    /**
     * @brief horner
     * @param d
     * @param remainder
     * @return
     */
    Polynomial horner(float d, float &remainder)
    {
        int nCoeff = coeff.size();
        Polynomial p(nCoeff - 1);

        p.coeff[nCoeff - 2] = coeff[nCoeff - 1];

        for(int i = (nCoeff - 3); i >= 0 ; i--) {
            p.coeff[i] = (p.coeff[i + 1] * d + coeff[i + 1]);
        }

        p.computeAllCoeffPositive();

        remainder = coeff[0] + p.coeff[0] * d;

        return p;
    }

    /**
     * @brief getRoots
     * @param x
     * @return
     */
    bool getRoots(float *x)
    {
        int nCoeff = coeff.size();

        if(nCoeff < 2) {
            return false;
        }

        if(nCoeff == 2) {
            //this coefficient may be not positive
            if(coeff[1] > 0.0f) {
                x[0] = -coeff[0] / coeff[1];
                return true;
            } else {
                return false;
            }
        }

        if(nCoeff == 3) {
            //these coefficients may be not positive
            return getSecondOrderRoots(coeff[2], coeff[1], coeff[0], &x[0], &x[1]);
        }

        if(all_coeff_positive) {
            return false;
        }

        float max_coeff0 = -1.0f;

        for(int i = 1; i < coeff.size(); i++) {
            float tmp = fabsf(coeff[i]);
            if(tmp > max_coeff0) {
                max_coeff0 = tmp;
            }
        }

        float tmp = fabsf(coeff[0]);
        float max_coeff;
        if(max_coeff0 < tmp) {
            max_coeff = tmp;
        } else {
            max_coeff = max_coeff0;
        }

        float lower_bound = fabsf(coeff[0]) / (fabsf(coeff[0]) + max_coeff0);

#ifdef PIC_DEBUG
        float upper_bound = 1.0f + max_coeff / fabsf(coeff[0]);
        printf("Upper bound: %f\n", upper_bound);
        printf("Lower bound: %f\n", lower_bound);
#endif

        float x_p = lower_bound;
        float x_n;
        bool notConverged = true;
        int counter = 0;
        float E_x_p;
        while(notConverged) {
            E_x_p = eval(x_p);
            x_n = x_p - E_x_p / dEval(x_p);
            x_p = x_n;
            counter++;

            notConverged = (fabsf(E_x_p) > 1e-4f) && (counter < 200);
        }

        if(counter == 200) {
            return false;
        } else {
            *x = x_n;
            return true;
        }
    }

    /**
     * @brief getAllRoots
     * @param x
     * @return
     */
    bool getAllRoots(float *x)
    {
        for(int i = 0; i < coeff.size() - 1; i++) {
            x[i] = FLT_MAX;
        }

        bool bOut = getRoots(&x[0]);

        if(!bOut) {
            return false;
        }

        float r;
        Polynomial p = horner(x[0], r);
        p.normalForm();

        int nCoeff = coeff.size();
        for(int i = 1; i < (nCoeff - 2); i++) {
            bool bOut = p.getRoots(&x[i]);

            if(!bOut) {
                return true;
            }

            p = p.horner(x[i], r);
            p.normalForm();
        }

        return true;
    }

    /**
     * @brief getQuarticRoots --> MANDATORY p[5] == 1.0
     * @param p
     * @param x
     * @return
     */
    static bool getQuarticRoots(float *p, float *x)
    {
#ifndef PIC_DISABLE_EIGEN
        Eigen::Matrix4f m;

        m << -p[3], -p[2], -p[1], -p[0],
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f;

        Eigen::EigenSolver<Eigen::Matrix4f> es(m);
        Eigen::Vector4cf e = es.eigenvalues();

        bool bOut = false;
        if(fabsf(e(0).imag()) < 1e-6f) {
            x[0] = e(0).real();
            bOut = true;
        }

        if(fabsf(e(1).imag()) < 1e-6f) {
            x[1] = e(1).real();
            bOut = true;
        }

        if(fabsf(e(2).imag()) < 1e-6f) {
            x[2] = e(2).real();
            bOut = true;
        }

        if(fabsf(e(3).imag()) < 1e-6f) {
            x[3] = e(3).real();
            bOut = true;
        }

        return bOut;
#else
        return true;
#endif
    }

    //Solver for second order equations, ax^2 + b x + c = 0
    static bool getSecondOrderRoots(float a, float b, float c, float *x0, float *x1)
    {
        float delta = b * b - 4.0f * a * c;

        if(delta >= 0.0f) {
            float dnum = 2.0f * a;
            delta = sqrtf(delta);
            *x0 = (-b + delta) / dnum;
            *x1 = (-b - delta) / dnum;
            return true;
        } else {
            return false;
        }
    }

    //Solver for second order equations, ax^2 + b x + c = 0, when b is even
    static bool getSecondOrderRootsS(float a, float b, float c, float *x0, float *x1)
    {
        float delta = b * b - a * c;
        if(delta >= 0.0f) {
            delta = sqrtf(delta);
            *x0 = (-b + delta) / a;
            *x1 = (-b - delta) / a;
            return true;
        } else {
            return false;
        }
    }

};

} // end namespace pic

#endif //PIC_UTIL_coeffNOMIAL_HPP
<|endoftext|>


<commit_before>// Copyright ***********************************************************
//
// File ecmdMain.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 1996
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/* $Header$ */

// Module Description **************************************************
//
// Description:
//
// End Module Description **********************************************
/**
 @file ecmdMain.C
 @brief Main Program entry point for ecmdDllClient Application
*/

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define ecmdMain_C

#include <stdio.h>
#include <string>

#include <ecmdClientCapi.H>
#include <ecmdInterpreter.H>
#include <ecmdReturnCodes.H>
#include <ecmdCommandUtils.H>
#include <ecmdSharedUtils.H>

#undef ecmdMain_C

int main (int argc, char *argv[])
{
  uint32_t rc = 0;

  std::string cmdsave;
  char buf[200];
  for (int i = 0; i < argc; i++) {
    cmdsave += argv[i];
    cmdsave += " ";
  }

  cmdsave += "\n";

  if (getenv ("ECMD_DLL_FILE") == NULL) {
    printf("ecmd - You must set ECMD_DLL_FILE in order to run the eCMD command line client\n");
    rc = ECMD_INVALID_DLL_FILENAME;
  } else {
    /* Load the one specified by ECMD_DLL_FILE */
    rc = ecmdLoadDll("");
  }

  if (rc == ECMD_SUCCESS) {

    /* Check to see if we are using stdin to pass in multiple commands */
    if (ecmdParseOption(&argc, &argv, "-stdin")) {

      /* Grab any other args that may be there */
      rc = ecmdCommandArgs(&argc, &argv);
      if (rc) return rc;

      /* There shouldn't be any more args when doing a -stdin */
      if (argc > 1) {
        ecmdOutputError("ecmd - Invalid args passed to ecmd in -stdin mode\n");
        rc = ECMD_INVALID_ARGS;

      } else {

        std::vector< std::string > commands;
        int   c_argc;
        char* c_argv[21];       ///< A limit of 20 tokens(args) per command
        char* buffer = NULL;
        int   bufflen = 0;
        int   commlen;

        /* ecmdParseStdInCommands reads from stdin and returns a vector of strings */
        /*  each string contains one command (ie 'ecmdquery version')              */
        /* When Ctrl-D or EOF is reached this function will fail to break out of loop */
        while ((rc = ecmdParseStdinCommands(commands)) != ECMD_SUCCESS) {

          rc = 0;

          /* Walk through individual commands from ecmdParseStdInCommands */
          for (std::vector< std::string >::iterator commit = commands.begin(); commit != commands.end(); commit ++) {

            c_argc = 0;

            /* Create a char buffer to hold the whole command, we will use this to create pointers to each token in the command (like argc,argv) */
            commlen = commit->length();
            if ( commlen > bufflen) {
              if (buffer != NULL) delete[] buffer;
              buffer = new char[commlen + 20];
              bufflen = commlen + 19;
            }

            // Beam "error" of possible NULL 'buffer' value requires mutually
            // exclusive conditions (need an argument present to enter
            // "commands" FOR loop but commit->length = 0 ie. no command).  So
            // tell beam to ignore NULL pointer message for 'buffer' parm via
            // comment on next line.
            strcpy(buffer, commit->c_str()); /*passing null object*/

            /* Now start carving this thing up */
            bool lookingForStart = true; /* Are we looking for the start of a word ? */
            for (int c = 0; c < commlen; c++) {
              if (lookingForStart) {
                if (buffer[c] != ' ' && buffer[c] != '\t') {
                  c_argv[c_argc++] = &buffer[c];
                  lookingForStart = false;
                }
              } else {
                /* Looking for the end */
                if (buffer[c] == ' ' || buffer[c] == '\t') {
                  buffer[c] = '\0';
                  lookingForStart = true;
                }
              }
              if (c_argc > 20) {
                ecmdOutputError("ecmd - Found a command with greater then 20 arguments, not supported\n");
                rc = ECMD_INVALID_ARGS;
                break;
              }
            }

            /* We now want to call the command interpreter to handle what the user provided us */
            if (!rc) rc = ecmdCallInterpreters(c_argc, c_argv);

            if (rc == ECMD_INT_UNKNOWN_COMMAND) {
              if (strlen(c_argv[0]) < 200)
                sprintf(buf,"ecmd -  Unknown Command specified '%s'\n", c_argv[0]);
              else
                sprintf(buf,"ecmd -  Unknown Command specified \n");
              ecmdOutputError(buf);
            } else if (rc) {
              std::string parse = ecmdGetErrorMsg(rc, false);
              if (parse.length() > 0) {
                /* Display the registered message right away BZ#160 */
                ecmdOutput(parse.c_str());
              }
              parse = ecmdParseReturnCode(rc);
              if (strlen(c_argv[0]) + parse.length() < 300)
                sprintf(buf,"ecmd - '%s' returned with error code %X (%s)\n", c_argv[0], rc, parse.c_str());
              else
                sprintf(buf,"ecmd - Command returned with error code %X (%s)\n", rc, parse.c_str());
              ecmdOutputError(buf);
              break;
            }

            if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
              ecmdOutput((*commit + "\n").c_str());
            }

          } /* tokens loop */
          if (rc) break;

        }
        if (buffer != NULL) delete[] buffer;

      } /* invalid args if */

    } else {
      /* Standard command line command */

      /* We now want to call the command interpreter to handle what the user provided us */
      rc = ecmdCallInterpreters(argc - 1, argv + 1);

      if (rc == ECMD_INT_UNKNOWN_COMMAND) {
        if (strlen(argv[1]) < 200)
          sprintf(buf,"ecmd -  Unknown Command specified '%s'\n", argv[1]);
        else
          sprintf(buf,"ecmd -  Unknown Command specified \n");
        ecmdOutputError(buf);
      } else if (rc) {
        std::string parse = ecmdGetErrorMsg(rc, false);
        if (parse.length() > 0) {
          /* Display the registered message right away BZ#160 */
          ecmdOutput(parse.c_str());
        }
        parse = ecmdParseReturnCode(rc);
        if (strlen(argv[1]) + parse.length() < 300)
          sprintf(buf,"ecmd - '%s' returned with error code %X (%s)\n", argv[1], rc, parse.c_str());
        else
          sprintf(buf,"ecmd - Command returned with error code %X (%s)\n", rc, parse.c_str());
        ecmdOutputError(buf);
      }
    }

    /* Move these outputs into the if !rc to fix BZ#224 - cje */
    if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
      ecmdOutput(cmdsave.c_str());
    }

    ecmdUnloadDll();

  }

  exit(rc);

}

// Change Log *********************************************************
//
//  Flag Reason   Vers Date     Coder    Description
//  ---- -------- ---- -------- -------- ------------------------------
//                              CENGEL   Initial Creation
//  none STGC7449      04/18/05 prahl    Clean up Beam messages.
//
// End Change Log *****************************************************
<commit_msg>Fixed segfault with no args<commit_after>// Copyright ***********************************************************
//
// File ecmdMain.C
//
// IBM Confidential
// OCO Source Materials
// 9400 Licensed Internal Code
// (C) COPYRIGHT IBM CORP. 1996
//
// The source code for this program is not published or otherwise
// divested of its trade secrets, irrespective of what has been
// deposited with the U.S. Copyright Office.
//
// End Copyright *******************************************************
/* $Header$ */

// Module Description **************************************************
//
// Description:
//
// End Module Description **********************************************
/**
 @file ecmdMain.C
 @brief Main Program entry point for ecmdDllClient Application
*/

//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define ecmdMain_C

#include <stdio.h>
#include <string>

#include <ecmdClientCapi.H>
#include <ecmdInterpreter.H>
#include <ecmdReturnCodes.H>
#include <ecmdCommandUtils.H>
#include <ecmdSharedUtils.H>

#undef ecmdMain_C

int main (int argc, char *argv[])
{
  uint32_t rc = 0;

  std::string cmdsave;
  char buf[200];
  for (int i = 0; i < argc; i++) {
    cmdsave += argv[i];
    cmdsave += " ";
  }

  cmdsave += "\n";

  if (getenv ("ECMD_DLL_FILE") == NULL) {
    printf("ecmd - You must set ECMD_DLL_FILE in order to run the eCMD command line client\n");
    rc = ECMD_INVALID_DLL_FILENAME;
  } else {
    /* Load the one specified by ECMD_DLL_FILE */
    rc = ecmdLoadDll("");
  }

  if (rc == ECMD_SUCCESS) {

    /* Check to see if we are using stdin to pass in multiple commands */
    if (ecmdParseOption(&argc, &argv, "-stdin")) {

      /* Grab any other args that may be there */
      rc = ecmdCommandArgs(&argc, &argv);
      if (rc) return rc;

      /* There shouldn't be any more args when doing a -stdin */
      if (argc > 1) {
        ecmdOutputError("ecmd - Invalid args passed to ecmd in -stdin mode\n");
        rc = ECMD_INVALID_ARGS;

      } else {

        std::vector< std::string > commands;
        int   c_argc;
        char* c_argv[21];       ///< A limit of 20 tokens(args) per command
        char* buffer = NULL;
        int   bufflen = 0;
        int   commlen;

        /* ecmdParseStdInCommands reads from stdin and returns a vector of strings */
        /*  each string contains one command (ie 'ecmdquery version')              */
        /* When Ctrl-D or EOF is reached this function will fail to break out of loop */
        while ((rc = ecmdParseStdinCommands(commands)) != ECMD_SUCCESS) {

          rc = 0;

          /* Walk through individual commands from ecmdParseStdInCommands */
          for (std::vector< std::string >::iterator commit = commands.begin(); commit != commands.end(); commit ++) {

            c_argc = 0;

            /* Create a char buffer to hold the whole command, we will use this to create pointers to each token in the command (like argc,argv) */
            commlen = commit->length();
            if ( commlen > bufflen) {
              if (buffer != NULL) delete[] buffer;
              buffer = new char[commlen + 20];
              bufflen = commlen + 19;
            }

            // Beam "error" of possible NULL 'buffer' value requires mutually
            // exclusive conditions (need an argument present to enter
            // "commands" FOR loop but commit->length = 0 ie. no command).  So
            // tell beam to ignore NULL pointer message for 'buffer' parm via
            // comment on next line.
            strcpy(buffer, commit->c_str()); /*passing null object*/

            /* Now start carving this thing up */
            bool lookingForStart = true; /* Are we looking for the start of a word ? */
            for (int c = 0; c < commlen; c++) {
              if (lookingForStart) {
                if (buffer[c] != ' ' && buffer[c] != '\t') {
                  c_argv[c_argc++] = &buffer[c];
                  lookingForStart = false;
                }
              } else {
                /* Looking for the end */
                if (buffer[c] == ' ' || buffer[c] == '\t') {
                  buffer[c] = '\0';
                  lookingForStart = true;
                }
              }
              if (c_argc > 20) {
                ecmdOutputError("ecmd - Found a command with greater then 20 arguments, not supported\n");
                rc = ECMD_INVALID_ARGS;
                break;
              }
            }

            /* We now want to call the command interpreter to handle what the user provided us */
            if (!rc) rc = ecmdCallInterpreters(c_argc, c_argv);

            if (rc == ECMD_INT_UNKNOWN_COMMAND) {
              if (strlen(c_argv[0]) < 200)
                sprintf(buf,"ecmd -  Unknown Command specified '%s'\n", c_argv[0]);
              else
                sprintf(buf,"ecmd -  Unknown Command specified \n");
              ecmdOutputError(buf);
            } else if (rc) {
              std::string parse = ecmdGetErrorMsg(rc, false);
              if (parse.length() > 0) {
                /* Display the registered message right away BZ#160 */
                ecmdOutput(parse.c_str());
              }
              parse = ecmdParseReturnCode(rc);
              if (strlen(c_argv[0]) + parse.length() < 300)
                sprintf(buf,"ecmd - '%s' returned with error code %X (%s)\n", c_argv[0], rc, parse.c_str());
              else
                sprintf(buf,"ecmd - Command returned with error code %X (%s)\n", rc, parse.c_str());
              ecmdOutputError(buf);
              break;
            }

            if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
              ecmdOutput((*commit + "\n").c_str());
            }

          } /* tokens loop */
          if (rc) break;

        }
        if (buffer != NULL) delete[] buffer;

      } /* invalid args if */

    } else {
      /* Standard command line command */

      /* We now want to call the command interpreter to handle what the user provided us */
      rc = ecmdCallInterpreters(argc - 1, argv + 1);

      if (rc == ECMD_INT_UNKNOWN_COMMAND) {
        if (argv[1] == NULL)
          sprintf(buf,"ecmd - Must specify a command to execute\n");
        else if (strlen(argv[1]) < 200)
          sprintf(buf,"ecmd - Unknown Command specified '%s'\n", argv[1]);
        else
          sprintf(buf,"ecmd - Unknown Command specified \n");
        ecmdOutputError(buf);
      } else if (rc) {
        std::string parse = ecmdGetErrorMsg(rc, false);
        if (parse.length() > 0) {
          /* Display the registered message right away BZ#160 */
          ecmdOutput(parse.c_str());
        }
        parse = ecmdParseReturnCode(rc);
        if (strlen(argv[1]) + parse.length() < 300)
          sprintf(buf,"ecmd - '%s' returned with error code %X (%s)\n", argv[1], rc, parse.c_str());
        else
          sprintf(buf,"ecmd - Command returned with error code %X (%s)\n", rc, parse.c_str());
        ecmdOutputError(buf);
      }
    }

    /* Move these outputs into the if !rc to fix BZ#224 - cje */
    if (!ecmdGetGlobalVar(ECMD_GLOBALVAR_QUIETMODE)) {
      ecmdOutput(cmdsave.c_str());
    }

    ecmdUnloadDll();

  }

  exit(rc);

}

// Change Log *********************************************************
//
//  Flag Reason   Vers Date     Coder    Description
//  ---- -------- ---- -------- -------- ------------------------------
//                              CENGEL   Initial Creation
//  none STGC7449      04/18/05 prahl    Clean up Beam messages.
//
// End Change Log *****************************************************
<|endoftext|>


<commit_before>//	DDCPP/standard/bits/DD_partial_sum.hpp
#ifndef DD_PARTIAL_SUM_INCLUDED_
#	define DD_PARTIAL_SUM_INCLUDED_ 1

#	include "DD_Iterator.hpp"
#	include "DD_Range.hpp"
#	include "DD_next.hpp"

DD_DETAIL_BEGIN_
template <typename UndirectionalIteratorT1_, typename UndirectionalIteratorT2_>
UndirectionalIteratorT2_ partial_sum(
	UndirectionalIteratorT1_ begin__,
	UndirectionalIteratorT1_ end__,
	UndirectionalIteratorT2_ result_begin__
) {
	if (begin__ != end__) {
		*result_begin__ = *begin__;
		for (; ++begin__ != end__; ++result_begin__) {
			*::DD::next(result_begin__) = *result_begin__ + *begin__;
		}
	}
	return result_begin__;
}

template <typename UndirectionalIteratorT1_, typename UndirectionalIteratorT2_>
Pair<UndirectionalIteratorT1_, UndirectionalIteratorT2_> partial_sum(
	UndirectionalIteratorT1_ begin__,
	UndirectionalIteratorT1_ end__,
	UndirectionalIteratorT1_ result_begin__,
	UndirectionalIteratorT1_ result_end__
) {
	if (begin__ != end__ && result_begin__ != result_end__) {
		*result_begin__ = *begin__;
		for (; ++begin__ != end__ && ::DD::next(result_end__) != end__; ++result_begin__) {
			*::DD::next(result_begin__) = *result_begin__ + *begin__;
		}
	}
	return Pair<UndirectionalIteratorT1_, UndirectionalIteratorT2_>(begin__, result_begin__);
}

DD_DETAIL_END_

DD_BEGIN_
using detail_::partial_sum;

DD_END_

#endif
<commit_msg>Add more overloaded version for 'DD::partial_sum'<commit_after>//	DDCPP/standard/bits/DD_partial_sum.hpp
#ifndef DD_PARTIAL_SUM_INCLUDED_
#	define DD_PARTIAL_SUM_INCLUDED_ 1

#	include "DD_Iterator.hpp"
#	include "DD_Range.hpp"
#	include "DD_next.hpp"

DD_DETAIL_BEGIN_
template <typename UndirectionalIteratorT1_, typename UndirectionalIteratorT2_>
UndirectionalIteratorT2_ partial_sum(
	UndirectionalIteratorT1_ begin__,
	UndirectionalIteratorT1_ end__,
	UndirectionalIteratorT2_ result_begin__
) {
	if (begin__ != end__) {
		*result_begin__ = *begin__;
		for (; ++begin__ != end__; ++result_begin__) {
			*::DD::next(result_begin__) = *result_begin__ + *begin__;
		}
	}
	return result_begin__;
}

template <typename UndirectionalIteratorT1_, typename UndirectionalIteratorT2_, typename BinaryFunctionT_>
UndirectionalIteratorT2_ partial_sum(
	UndirectionalIteratorT1_ begin__,
	UndirectionalIteratorT1_ end__,
	UndirectionalIteratorT2_ result_begin__,
	BinaryFunctionT_ add__
) {
	if (begin__ != end__) {
		*result_begin__ = *begin__;
		for (; ++begin__ != end__; ++result_begin__) {
			*::DD::next(result_begin__) = add__(*result_begin__, *begin__);
		}
	}
	return result_begin__;
}

template <typename UndirectionalIteratorT1_, typename UndirectionalIteratorT2_>
Pair<UndirectionalIteratorT1_, UndirectionalIteratorT2_> partial_sum(
	UndirectionalIteratorT1_ begin__,
	UndirectionalIteratorT1_ end__,
	UndirectionalIteratorT1_ result_begin__,
	UndirectionalIteratorT1_ result_end__
) {
	if (begin__ != end__ && result_begin__ != result_end__) {
		*result_begin__ = *begin__;
		for (; ++begin__ != end__ && ::DD::next(result_end__) != end__; ++result_begin__) {
			*::DD::next(result_begin__) = *result_begin__ + *begin__;
		}
	}
	return Pair<UndirectionalIteratorT1_, UndirectionalIteratorT2_>(begin__, result_begin__);
}

template <typename UndirectionalIteratorT1_, typename UndirectionalIteratorT2_, typename BinaryFunctionT_>
Pair<UndirectionalIteratorT1_, UndirectionalIteratorT2_> partial_sum(
	UndirectionalIteratorT1_ begin__,
	UndirectionalIteratorT1_ end__,
	UndirectionalIteratorT1_ result_begin__,
	UndirectionalIteratorT1_ result_end__,
	BinaryFunctionT_ add__
) {
	if (begin__ != end__ && result_begin__ != result_end__) {
		*result_begin__ = *begin__;
		for (; ++begin__ != end__ && ::DD::next(result_end__) != end__; ++result_begin__) {
			*::DD::next(result_begin__) = add__(*result_begin__, *begin__);
		}
	}
	return Pair<UndirectionalIteratorT1_, UndirectionalIteratorT2_>(begin__, result_begin__);
}

template <typename UndirectionalRangeT1_, typename UndirectionalRangeT2_>
inline Pair<DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT1_), DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT2_)> partial_sum(
	UndirectionalRangeT1_& range__,
	UndirectionalRangeT1_& result_range__
) DD_NOEXCEPT_AS(static_cast<Pair<DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT1_) DD_COMMA DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT2_)>>(
	::DD::detail_::partial_sum(DD_SPLIT_RANGE(range__) DD_COMMA DD_SPLIT_RANGE(result_range__))
)) {
	return ::DD::detail_::partial_sum(DD_SPLIT_RANGE(range__), DD_SPLIT_RANGE(result_range__));
}

template <typename UndirectionalRangeT1_, typename UndirectionalRangeT2_, typename BinaryFunctionT_>
inline Pair<DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT1_), DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT2_)> partial_sum(
	UndirectionalRangeT1_& range__,
	UndirectionalRangeT1_& result_range__,
	BinaryFunctionT_ add__
) DD_NOEXCEPT_AS(static_cast<Pair<DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT1_) DD_COMMA DD_MODIFY_TRAIT(Iterator, UndirectionalRangeT2_)>>(
	::DD::detail_::partial_sum(DD_SPLIT_RANGE(range__) DD_COMMA DD_SPLIT_RANGE(result_range__) DD_COMMA add__)
)) {
	return ::DD::detail_::partial_sum(DD_SPLIT_RANGE(range__), DD_SPLIT_RANGE(result_range__), add__);
}

DD_DETAIL_END_

DD_BEGIN_
using detail_::partial_sum;

DD_END_

#endif
<|endoftext|>


<commit_before>#include "vast/util/command_line.h"

namespace vast {
namespace util {

bool command_line::mode_add(std::string name,
                            std::string desc,
                            std::string prompt,
                            std::string history_file)
{
  if (modes_.count(name))
    return false;
  auto m = std::make_shared<mode>(
      std::move(name), std::move(desc),
      std::move(prompt), std::move(history_file));
  modes_.emplace(m->name, m);
  return true;
}

bool command_line::mode_rm(std::string const& name)
{
  if (! modes_.count(name))
    return false;
  modes_.erase(name);
  return true;
}

bool command_line::mode_push(std::string const& mode)
{
  if (! modes_.count(mode))
    return false;
  mode_stack_.push_back(modes_[mode]);
  return true;
}

bool command_line::mode_pop()
{
  if (mode_stack_.empty())
    return false;
  mode_stack_.pop_back();
  return true;
}

bool command_line::cmd_add(std::string const& mode, std::string cmd, callback f)
{
  if (! modes_.count(mode))
    return false;
  auto& m = *modes_[mode];
  if (m.callbacks.count(cmd))
    return false;
  m.el.complete(cmd);
  m.callbacks.emplace(std::move(cmd), std::move(f));
  return true;
}

bool command_line::cmd_rm(std::string const& mode, std::string const& cmd)
{
  if (! modes_.count(mode))
    return false;
  auto& m = *modes_[mode];
  if (! m.callbacks.count(cmd))
    return false;
  m.callbacks.erase(cmd);
  return true;
}

bool command_line::on_unknown_command(std::string const& mode, callback f)
{
  if (! modes_.count(mode))
    return false;
  auto& m = *modes_[mode];
  m.unknown_command = f;
  return true;
}

bool command_line::append_to_history(std::string const& entry)
{
  if (mode_stack_.empty())
    return false;
  mode_stack_.back()->hist.enter(entry);
  mode_stack_.back()->hist.save();
  return true;
}

bool command_line::process(bool& callback_result)
{
  if (mode_stack_.empty())
    return false;
  auto current = mode_stack_.back();
  current->el.reset();  // Fixes TTY weirdness when switching between modes.
  std::string cmd;
  if (! current->el.get(cmd))
    return false;
  // Trim string.
  auto first_non_ws = cmd.find_first_not_of(" \t");
  auto last_non_ws = cmd.find_last_not_of(" \t");
  if (first_non_ws != std::string::npos)
    cmd = cmd.substr(first_non_ws, last_non_ws - first_non_ws + 1);
  auto space = cmd.find(' ');
  auto key = cmd.substr(0, space);
  if (! current->callbacks.count(key))
  {
    if (! current->unknown_command)
      return false;
    callback_result = current->unknown_command(std::move(cmd));
    return true;
  }
  auto args = space == std::string::npos ? cmd : cmd.substr(++space);
  callback_result = current->callbacks[key](std::move(args));
  current->hist.enter(cmd);
  current->hist.save();
  return true;
}

bool command_line::get(char& c)
{
  return mode_stack_.empty() ? false : mode_stack_.back()->el.get(c);
}

command_line::mode::mode(std::string name,
                         std::string desc,
                         std::string prompt,
                         std::string filename)
  : name{std::move(name)},
    description{std::move(desc)},
    hist{1000, true, std::move(filename)}
{
  el.source();
  el.set(hist);
  if (! prompt.empty())
    el.set(editline::prompt{std::move(prompt)});
}

} // namespace util
} // namespace vast
<commit_msg>Add extra space after completion.<commit_after>#include "vast/util/command_line.h"

namespace vast {
namespace util {

bool command_line::mode_add(std::string name,
                            std::string desc,
                            std::string prompt,
                            std::string history_file)
{
  if (modes_.count(name))
    return false;
  auto m = std::make_shared<mode>(
      std::move(name), std::move(desc),
      std::move(prompt), std::move(history_file));
  modes_.emplace(m->name, m);
  return true;
}

bool command_line::mode_rm(std::string const& name)
{
  if (! modes_.count(name))
    return false;
  modes_.erase(name);
  return true;
}

bool command_line::mode_push(std::string const& mode)
{
  if (! modes_.count(mode))
    return false;
  mode_stack_.push_back(modes_[mode]);
  return true;
}

bool command_line::mode_pop()
{
  if (mode_stack_.empty())
    return false;
  mode_stack_.pop_back();
  return true;
}

bool command_line::cmd_add(std::string const& mode, std::string cmd, callback f)
{
  if (! modes_.count(mode))
    return false;
  auto& m = *modes_[mode];
  if (m.callbacks.count(cmd))
    return false;
  m.el.complete(cmd + ' ');
  m.callbacks.emplace(std::move(cmd), std::move(f));
  return true;
}

bool command_line::cmd_rm(std::string const& mode, std::string const& cmd)
{
  if (! modes_.count(mode))
    return false;
  auto& m = *modes_[mode];
  if (! m.callbacks.count(cmd))
    return false;
  m.callbacks.erase(cmd);
  return true;
}

bool command_line::on_unknown_command(std::string const& mode, callback f)
{
  if (! modes_.count(mode))
    return false;
  auto& m = *modes_[mode];
  m.unknown_command = f;
  return true;
}

bool command_line::append_to_history(std::string const& entry)
{
  if (mode_stack_.empty())
    return false;
  mode_stack_.back()->hist.enter(entry);
  mode_stack_.back()->hist.save();
  return true;
}

bool command_line::process(bool& callback_result)
{
  if (mode_stack_.empty())
    return false;
  auto current = mode_stack_.back();
  current->el.reset();  // Fixes TTY weirdness when switching between modes.
  std::string cmd;
  if (! current->el.get(cmd))
    return false;
  // Trim string.
  auto first_non_ws = cmd.find_first_not_of(" \t");
  auto last_non_ws = cmd.find_last_not_of(" \t");
  if (first_non_ws != std::string::npos)
    cmd = cmd.substr(first_non_ws, last_non_ws - first_non_ws + 1);
  auto space = cmd.find(' ');
  auto key = cmd.substr(0, space);
  if (! current->callbacks.count(key))
  {
    if (! current->unknown_command)
      return false;
    callback_result = current->unknown_command(std::move(cmd));
    return true;
  }
  auto args = space == std::string::npos ? cmd : cmd.substr(++space);
  callback_result = current->callbacks[key](std::move(args));
  current->hist.enter(cmd);
  current->hist.save();
  return true;
}

bool command_line::get(char& c)
{
  return mode_stack_.empty() ? false : mode_stack_.back()->el.get(c);
}

command_line::mode::mode(std::string name,
                         std::string desc,
                         std::string prompt,
                         std::string filename)
  : name{std::move(name)},
    description{std::move(desc)},
    hist{1000, true, std::move(filename)}
{
  el.source();
  el.set(hist);
  if (! prompt.empty())
    el.set(editline::prompt{std::move(prompt)});
}

} // namespace util
} // namespace vast
<|endoftext|>