<commit_before>#pragma once

#include "mtao/types.h"

namespace mtao { namespace eigen {

    template <bool Row=false,typename Derived>
        auto slice_filter(const Eigen::MatrixBase<Derived>& A, const mtao::VectorX<bool>& M) {

            using Scalar = typename Derived::Scalar;
            constexpr static int  RACT = Row ? Eigen::Dynamic: Derived::RowsAtCompileTime;
            constexpr static int  CACT = Row ? Derived::ColsAtCompileTime : Eigen::Dynamic;

            int size = M.count();

            using Mat = Eigen::Matrix<Scalar,RACT,CACT>;
            Mat B( Row?size:A.rows(),Row?A.cols():size);

            int c = 0;
            for(int i = 0; i < (Row?A.rows():A.cols()); ++i) {
                if(M(i)) {
                    if constexpr(Row) {
                    B.row(c++) = A.row(i);
                    } else {
                    B.col(c++) = A.col(i);
                    }
                }
            }
            return B;
        }
    template <typename Derived>
        auto row_slice_filter(const Eigen::MatrixBase<Derived>& A, const mtao::VectorX<bool>& M) {
            return slice_filter<true>(A,M);
        }

    template <typename Derived>
        auto col_slice_filter(const Eigen::MatrixBase<Derived>& A, const mtao::VectorX<bool>& M) {
            return slice_filter<false>(A,M);
        }

}}
<commit_msg>indentation<commit_after>#pragma once

#include "mtao/types.h"

namespace mtao { namespace eigen {

    template <bool Row=false,typename Derived>
        auto slice_filter(const Eigen::MatrixBase<Derived>& A, const mtao::VectorX<bool>& M) {

            using Scalar = typename Derived::Scalar;
            constexpr static int  RACT = Row ? Eigen::Dynamic: Derived::RowsAtCompileTime;
            constexpr static int  CACT = Row ? Derived::ColsAtCompileTime : Eigen::Dynamic;

            int size = M.count();

            using Mat = Eigen::Matrix<Scalar,RACT,CACT>;
            Mat B( Row?size:A.rows(),Row?A.cols():size);

            int c = 0;
            for(int i = 0; i < (Row?A.rows():A.cols()); ++i) {
                if(M(i)) {
                    if constexpr(Row) {
                        B.row(c++) = A.row(i);
                    } else {
                        B.col(c++) = A.col(i);
                    }
                }
            }
            return B;
        }
    template <typename Derived>
        auto row_slice_filter(const Eigen::MatrixBase<Derived>& A, const mtao::VectorX<bool>& M) {
            return slice_filter<true>(A,M);
        }

    template <typename Derived>
        auto col_slice_filter(const Eigen::MatrixBase<Derived>& A, const mtao::VectorX<bool>& M) {
            return slice_filter<false>(A,M);
        }

}}
<|endoftext|>


<commit_before>#pragma once

#include <sdbusplus/asio/connection.hpp>

namespace sdbusplus::asio
{

template <typename Handler>
inline void getAllProperties(sdbusplus::asio::connection& bus,
                             const std::string& service,
                             const std::string& path,
                             const std::string& interface, Handler&& handler)
{
    bus.async_method_call(std::forward<Handler>(handler), service, path,
                          "org.freedesktop.DBus.Properties", "GetAll",
                          interface);
}

template <typename T, typename Handler>
inline void getProperty(sdbusplus::asio::connection& bus,
                        const std::string& service, const std::string& path,
                        const std::string& interface,
                        const std::string& propertyName, Handler&& handler)
{
    bus.async_method_call(
        [handler = std::forward<Handler>(handler)](
            boost::system::error_code ec,
            std::variant<std::monostate, T>& ret) {
            if (ec)
            {
                handler(ec, {});
                return;
            }

            if (T* value = std::get_if<T>(&ret))
            {
                handler(ec, *value);
                return;
            }

            handler(boost::system::errc::make_error_code(
                        boost::system::errc::invalid_argument),
                    {});
        },
        service, path, "org.freedesktop.DBus.Properties", "Get", interface,
        propertyName);
}

/* This method has been deprecated, and will be removed in a future revision.
 * Use the getProperty overload above to make equivalent calls
 */
template <typename T, typename OnError, typename OnSuccess>
[[deprecated]] inline void
    getProperty(sdbusplus::asio::connection& bus, const std::string& service,
                const std::string& path, const std::string& interface,
                const std::string& propertyName, OnError&& onError,
                OnSuccess&& onSuccess)
{
    bus.async_method_call(
        [onError = std::move(onError), onSuccess = std::move(onSuccess)](
            boost::system::error_code ec,
            std::variant<std::monostate, T>& ret) {
            if (ec)
            {
                onError(ec);
                return;
            }

            if (T* value = std::get_if<T>(&ret))
            {
                onSuccess(*value);
                return;
            }

            onError(boost::system::errc::make_error_code(
                boost::system::errc::invalid_argument));
        },
        service, path, "org.freedesktop.DBus.Properties", "Get", interface,
        propertyName);
}

template <typename T, typename Handler>
inline void setProperty(sdbusplus::asio::connection& bus,
                        const std::string& service, const std::string& path,
                        const std::string& interface,
                        const std::string& propertyName, T&& propertyValue,
                        Handler&& handler)
{
    bus.async_method_call(
        std::forward<Handler>(handler), service, path,
        "org.freedesktop.DBus.Properties", "Set", interface, propertyName,
        std::variant<std::decay_t<T>>(std::forward<T>(propertyValue)));
}

} // namespace sdbusplus::asio
<commit_msg>Used erased type to reduce binary for getProperty<commit_after>#pragma once

#include <sdbusplus/asio/connection.hpp>

namespace sdbusplus::asio
{

template <typename Handler>
inline void getAllProperties(sdbusplus::asio::connection& bus,
                             const std::string& service,
                             const std::string& path,
                             const std::string& interface, Handler&& handler)
{
    bus.async_method_call(std::forward<Handler>(handler), service, path,
                          "org.freedesktop.DBus.Properties", "GetAll",
                          interface);
}

template <typename T>
inline void
    getProperty(sdbusplus::asio::connection& bus, const std::string& service,
                const std::string& path, const std::string& interface,
                const std::string& propertyName,
                std::function<void(boost::system::error_code, T)>&& handler)
{
    static_assert(std::is_same_v<T, std::decay_t<T>>);

    bus.async_method_call(
        [handler = std::move(handler)](boost::system::error_code ec,
                                       std::variant<std::monostate, T>& ret) {
            if (ec)
            {
                handler(ec, {});
                return;
            }

            if (T* value = std::get_if<T>(&ret))
            {
                handler(ec, std::move(*value));
                return;
            }

            handler(boost::system::errc::make_error_code(
                        boost::system::errc::invalid_argument),
                    {});
        },
        service, path, "org.freedesktop.DBus.Properties", "Get", interface,
        propertyName);
}

/* This method has been deprecated, and will be removed in a future revision.
 * Use the getProperty overload above to make equivalent calls
 */
template <typename T, typename OnError, typename OnSuccess>
[[deprecated]] inline void
    getProperty(sdbusplus::asio::connection& bus, const std::string& service,
                const std::string& path, const std::string& interface,
                const std::string& propertyName, OnError&& onError,
                OnSuccess&& onSuccess)
{
    bus.async_method_call(
        [onError = std::move(onError), onSuccess = std::move(onSuccess)](
            boost::system::error_code ec,
            std::variant<std::monostate, T>& ret) {
            if (ec)
            {
                onError(ec);
                return;
            }

            if (T* value = std::get_if<T>(&ret))
            {
                onSuccess(*value);
                return;
            }

            onError(boost::system::errc::make_error_code(
                boost::system::errc::invalid_argument));
        },
        service, path, "org.freedesktop.DBus.Properties", "Get", interface,
        propertyName);
}

template <typename T, typename Handler>
inline void setProperty(sdbusplus::asio::connection& bus,
                        const std::string& service, const std::string& path,
                        const std::string& interface,
                        const std::string& propertyName, T&& propertyValue,
                        Handler&& handler)
{
    bus.async_method_call(
        std::forward<Handler>(handler), service, path,
        "org.freedesktop.DBus.Properties", "Set", interface, propertyName,
        std::variant<std::decay_t<T>>(std::forward<T>(propertyValue)));
}

} // namespace sdbusplus::asio
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "QuaternionDecorator.h"

namespace PythonScript {

    Quaternion* QuaternionDecorator::new_Quaternion(const float x, const float y, const float z, const float w) { return new Quaternion(x, y, z, w); }
    Quaternion* QuaternionDecorator::new_Quaternion(const float x, const float y, const float z) { return new Quaternion(x, y, z); }
    Quaternion* QuaternionDecorator::new_Quaternion(const Vector3df& vec) { return new Quaternion(vec); }
    Quaternion* QuaternionDecorator::new_Quaternion(const float angle, const Vector3df& vec) { return new Quaternion(angle, vec); }
    void QuaternionDecorator::delete_Quaternion(Quaternion* self) { delete self; }

    float QuaternionDecorator::x(Quaternion* self) { return self->x; }
    float QuaternionDecorator::y(Quaternion* self) { return self->y; }
    float QuaternionDecorator::z(Quaternion* self) { return self->z; }
    float QuaternionDecorator::w(Quaternion* self) { return self->w; }

    bool QuaternionDecorator::equals(Quaternion* self, const Quaternion& other, const float tolerance) { return self->equals(other, tolerance); }

    void QuaternionDecorator::setx(Quaternion* self, float value) { self->x = value; }
    void QuaternionDecorator::sety(Quaternion* self, float value) { self->y = value; }
    void QuaternionDecorator::setz(Quaternion* self, float value) { self->z = value; }
    void QuaternionDecorator::setw(Quaternion* self, float value) { self->w = value; }

    float QuaternionDecorator::dotProduct(Quaternion* self, const Quaternion& other)
    {
        return self->dotProduct(other);
    }

    void QuaternionDecorator::toEuler(Quaternion* self, Vector3df& euler) {
        self->toEuler(euler);
    }

    void QuaternionDecorator::set(Quaternion* self, float x, float y, float z, float w) {
        self->set(x, y, z, w);
    }

    void QuaternionDecorator::set(Quaternion* self, float x, float y, float z, float w) {
        self->set(x, y, z);
    }

    void QuaternionDecorator::set(Quaternion* self, const Vector3df& euler) {
        self->set(euler);
    }

    void QuaternionDecorator::normalize(Quaternion* self)
    {
        self->normalize();
    }

    void QuaternionDecorator::makeInverse(Quaternion* self)
    {
        self->makeInverse();
    }

    void QuaternionDecorator::slerp(Quaternion* self, Quaternion q1, Quaternion q2, float interpolate)
    {
        self->slerp(q1, q2, interpolate);
    }

    void QuaternionDecorator::fromAngleAxis(Quaternion* self, float angle, const Vector3df& axis)
    {
        self->fromAngleAxis(angle, axis);
    }

    void QuaternionDecorator::toAngleAxis(Quaternion* self, float& angle, Vector3df& axis)
    {
        self->toAngleAxis(angle, axis);
    }

    void QuaternionDecorator::makeIdentity(Quaternion* self)
    {
        self->makeIdentity();
    }

    void QuaternionDecorator::rotationFromTo(Quaternion* self, const Vector3df& from, const Vector3df& to)
    {
        self->rotationFromTo(from, to);
    }
}

<commit_msg>Small reorg<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "QuaternionDecorator.h"

namespace PythonScript {

    Quaternion* QuaternionDecorator::new_Quaternion(const float x, const float y, const float z, const float w)
    {
        return new Quaternion(x, y, z, w);
    }

    Quaternion* QuaternionDecorator::new_Quaternion(const float x, const float y, const float z)
    {
        return new Quaternion(x, y, z);
    }

    Quaternion* QuaternionDecorator::new_Quaternion(const Vector3df& vec)
    {
        return new Quaternion(vec);
    }

    Quaternion* QuaternionDecorator::new_Quaternion(const float angle, const Vector3df& vec)
    {
        return new Quaternion(angle, vec);
    }

    void QuaternionDecorator::delete_Quaternion(Quaternion* self)
    {
        delete self;
    }

    float QuaternionDecorator::x(Quaternion* self)
    {
        return self->x;
    }

    float QuaternionDecorator::y(Quaternion* self)
    {
        return self->y;
    }

    float QuaternionDecorator::z(Quaternion* self)
    {
        return self->z;
    }

    float QuaternionDecorator::w(Quaternion* self)
    {
        return self->w;
    }

    bool QuaternionDecorator::equals(Quaternion* self, const Quaternion& other, const float tolerance)
    {
        return self->equals(other, tolerance);
    }

    void QuaternionDecorator::setx(Quaternion* self, float value)
    {
        self->x = value;
    }

    void QuaternionDecorator::sety(Quaternion* self, float value)
    {
        self->y = value;
    }

    void QuaternionDecorator::setz(Quaternion* self, float value)
    {
        self->z = value;
    }

    void QuaternionDecorator::setw(Quaternion* self, float value)
    {
        self->w = value;
    }

    float QuaternionDecorator::dotProduct(Quaternion* self, const Quaternion& other)
    {
        return self->dotProduct(other);
    }

    void QuaternionDecorator::toEuler(Quaternion* self, Vector3df& euler)
    {
        self->toEuler(euler);
    }

    void QuaternionDecorator::set(Quaternion* self, float x, float y, float z, float w)
    {
        self->set(x, y, z, w);
    }

    void QuaternionDecorator::set(Quaternion* self, float x, float y, float z, float w)
    {
        self->set(x, y, z);
    }

    void QuaternionDecorator::set(Quaternion* self, const Vector3df& euler)
    {
        self->set(euler);
    }

    void QuaternionDecorator::normalize(Quaternion* self)
    {
        self->normalize();
    }

    void QuaternionDecorator::makeInverse(Quaternion* self)
    {
        self->makeInverse();
    }

    void QuaternionDecorator::slerp(Quaternion* self, Quaternion q1, Quaternion q2, float interpolate)
    {
        self->slerp(q1, q2, interpolate);
    }

    void QuaternionDecorator::fromAngleAxis(Quaternion* self, float angle, const Vector3df& axis)
    {
        self->fromAngleAxis(angle, axis);
    }

    void QuaternionDecorator::toAngleAxis(Quaternion* self, float& angle, Vector3df& axis)
    {
        self->toAngleAxis(angle, axis);
    }

    void QuaternionDecorator::makeIdentity(Quaternion* self)
    {
        self->makeIdentity();
    }

    void QuaternionDecorator::rotationFromTo(Quaternion* self, const Vector3df& from, const Vector3df& to)
    {
        self->rotationFromTo(from, to);
    }
}

<|endoftext|>


<commit_before>#include "DataSetTrainer.h"
#define _USE_MATH_DEFINES
#include <math.h>

DataSetTrainer::DataSetTrainer(std::vector<vector3d*>* space, std::vector<vector3d*>* vectors) {
	this->space = space;
	this->vectors = vectors;

	if (space == NULL && vectors == NULL) {
		this->a = 0;
		this->b = 0;
		this->c = 0;
		this->d = 0;
		this->e = 0;
		this->f = 0;
		this->g = 0;
		this->h = 0;
		this->i = 0;
		this->j = 0;
		this->k = 0;
		this->l = 0;
	}
	this->net = new dlib::mlp::kernel_1a_c(3, 10, 0L, 2);//3 input nodes, 5 hidden nodes on first layer, 0 nodes second layer, and 2 nodes output layer, rest default
	//really have no idea what i'm doing. Guess I'll be playing with those middle two values, and maybe others as well?
}

DataSetTrainer::~DataSetTrainer()
{
	delete this->space;
	delete this->vectors;
}

vector3d* DataSetTrainer::get_from_linear(vector3d* loc) {
	float r = (loc->xyz()[0] * this->a) + (loc->xyz()[1] * this->b) + (loc->xyz()[2] * this->c) + this->d;
	float theta = (loc->xyz()[0] * this->e) + (loc->xyz()[1] * this->f) + (loc->xyz()[2] * this->g) + this->h;
	float phi = (loc->xyz()[0] * this->i) + (loc->xyz()[1] * this->j) + (loc->xyz()[2] * this->k) + this->l;

	vector3d* ret = new vector3d(r, theta, phi,vector3d::spherical);
	//ret->xyz();
	return ret;
}

double DataSetTrainer::linear_model(const input_vector& input, const parameter_vector& params) {
	const double p0 = params(0);
	const double p1 = params(1);
	const double p2 = params(2);
	const double p3 = params(3);

	const double i0 = input(0);
	const double i1 = input(1);
	const double i2 = input(2);

	const double temp = p0*i0 + p1*i1 + p2*i2 + p3;

	return temp*temp; //because we're doing least squares
}

double DataSetTrainer::linear_residual(const std::pair<input_vector, double>& data, const parameter_vector& params) {
	return DataSetTrainer::linear_model(data.first, params) - data.second;
}
parameter_vector DataSetTrainer::residual_derivative(const std::pair<input_vector, double>& data, const parameter_vector& params){
	parameter_vector der;

	const double p0 = params(0);
	const double p1 = params(1);
	const double p2 = params(2);
	const double p3 = params(3);

	const double i0 = data.first(0);
	const double i1 = data.first(1);
	const double i2 = data.first(2);

	const double temp = p0*i0 + p1*i1 + p2*i2 + p3;

	der(0) = i0*2*temp;
	der(1) = i1*2*temp;
	der(2) = i2*2*temp;
	der(3) = 2*temp;

	return der;
}

//http://dlib.net/least_squares_ex.cpp.html
void DataSetTrainer::train_linear() {
	//going to need to do this three times. So, you know, will take time.
	std::vector<std::pair<input_vector, double> > data_samples;
	input_vector input;
	//get radius
	for(size_t i = 0; i<this->space->size(); i++){
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2]; //set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi
		data_samples.push_back(std::make_pair(input, vec[0]));//training for creating the radius
	}
	//now get constants
	parameter_vector x;
	x = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::linear_residual,
		dlib::derivative(DataSetTrainer::linear_residual),
		data_samples,
		x);
	//set constants for later use
	this->a = x(0);
	this->b = x(1);
	this->c = x(2);
	this->d = x(3);

	//get theta
	data_samples.clear();
	for(size_t i = 0; i<this->space->size(); i++){
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2];//set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi

		data_samples.push_back(std::make_pair(input, vec[1]));//training for creating the theta
	}
	parameter_vector x1;
	x1 = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::linear_residual,
		dlib::derivative(DataSetTrainer::linear_residual),
		data_samples,
		x1);
	//set constants for later use
	this->e = x1(0);
	this->f = x1(1);
	this->g = x1(2);
	this->h = x1(3);

	//get phi
	data_samples.clear();
	for(size_t i = 0; i<this->space->size(); i++){
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2];//set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi

		data_samples.push_back(std::make_pair(input, vec[2]));//training for creating the phi
	}
	parameter_vector x2;
	x2 = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::linear_residual,
		dlib::derivative(DataSetTrainer::linear_residual),
		data_samples,
		x2);
	//set constants for later use
	this->i = x2(0);
	this->j = x2(1);
	this->k = x2(2);
	this->l = x2(3);
	//AND DONE, FULLY TRAINED. MATHEMATICAL!!!!
}

double DataSetTrainer::hybrid_model(const input_vector& input, const parameter_vector& params) {
	const double p0 = params(0);
	const double p1 = params(1);
	const double p2 = params(2);
	const double p3 = params(3);

	const double i0 = input(0);
	const double i1 = input(1);
	const double i2 = input(2);

	const double temp = p0*i0 + p1*i1 + p2*i2 + p3;

	return temp*temp; //because we're doing least squares
}

double DataSetTrainer::hybrid_residual(const std::pair<input_vector, double>& data, const parameter_vector& params) {
	return DataSetTrainer::linear_model(data.first, params) - data.second;
}

void DataSetTrainer::train_hybrid() {
	//going to need to do this three times. So, you know, will take time.
	std::vector<std::pair<input_vector, double> > data_samples;
	input_vector input;
	//get radius
	for (size_t i = 0; i<this->space->size(); i++) {
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2]; //set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi
		data_samples.push_back(std::make_pair(input, vec[0]));//training for creating the radius

		//Neural Net Time
		input_vector pos_iv;
		neural_output vec_no;
		pos_iv(0) = pos[0];
		pos_iv(1) = pos[1];
		pos_iv(2) = pos[2];

		vec_no(0) = (vec[1] / (2 * M_PI))*0.9; //theta range is 0 - 2PI, so we shift down into [0,1] and down again into [0,0.9] to be safe
		vec_no(1) = (vec[2] / M_PI)*0.9; //phi range is 0-PI, so we shift down into [0,1] and down again into [0,0.9] to be safe

		this->net->train(pos_iv, vec_no);//min(vec_no) needs to be >=0.0. UGHHHHH
	}
	//now get constants for R
	parameter_vector x;
	x = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::hybrid_residual,
		dlib::derivative(DataSetTrainer::hybrid_residual),
		data_samples,
		x);
	//set constants for later use
	this->a = x(0);
	this->b = x(1);
	this->c = x(2);
	this->d = x(3);

}
vector3d* DataSetTrainer::get_from_hybrid(vector3d* loc) {
	//Get R
	float r = (loc->xyz()[0] * this->a) + (loc->xyz()[1] * this->b) + (loc->xyz()[2] * this->c) + this->d;
	//float theta = (loc->xyz()[0] * this->e) + (loc->xyz()[1] * this->f) + (loc->xyz()[2] * this->g) + this->h;
	//float phi = (loc->xyz()[0] * this->i) + (loc->xyz()[1] * this->j) + (loc->xyz()[2] * this->k) + this->l;

	//get THETA, and PHI
	dlib::mlp::kernel_1a_c* net = this->net;
	input_vector in;
	float* arr = loc->xyz();
	in(0) = arr[0];
	in(1) = arr[1];
	in(2) = arr[2];

	neural_output out;
	out = (*net)(in);//don't question the callback-like functionality of objects in c++. I know it's gross, just ignore.

	float theta = (out(0)/0.9) * (2 * M_PI); //shift out from [0,0.9] into [0,1] and then out agin into [0,2PI]
	float phi = (out(1)/0.9) * (M_PI); //shift out from [0,0.9] into [0,1] and then out agin into [0,PI]

	vector3d* ret = new vector3d(r, theta, phi, vector3d::spherical);
	//ret->xyz();
	return ret;
}
<commit_msg>few edits<commit_after>#include "DataSetTrainer.h"
#define _USE_MATH_DEFINES
#include <math.h>

DataSetTrainer::DataSetTrainer(std::vector<vector3d*>* space, std::vector<vector3d*>* vectors) {
	this->space = space;
	this->vectors = vectors;

	if (space == NULL && vectors == NULL) {
		this->a = 0;
		this->b = 0;
		this->c = 0;
		this->d = 0;
		this->e = 0;
		this->f = 0;
		this->g = 0;
		this->h = 0;
		this->i = 0;
		this->j = 0;
		this->k = 0;
		this->l = 0;
	}
	this->net = new dlib::mlp::kernel_1a_c(3, 10, 0L, 2);//3 input nodes, 10 hidden nodes on first layer, 0 nodes second layer, and 2 nodes output layer, rest default
	//really have no idea what i'm doing. Guess I'll be playing with those middle two values, and maybe others as well?
}

DataSetTrainer::~DataSetTrainer()
{
	delete this->space;
	delete this->vectors;
}

vector3d* DataSetTrainer::get_from_linear(vector3d* loc) {
	float r = (loc->xyz()[0] * this->a) + (loc->xyz()[1] * this->b) + (loc->xyz()[2] * this->c) + this->d;
	float theta = (loc->xyz()[0] * this->e) + (loc->xyz()[1] * this->f) + (loc->xyz()[2] * this->g) + this->h;
	float phi = (loc->xyz()[0] * this->i) + (loc->xyz()[1] * this->j) + (loc->xyz()[2] * this->k) + this->l;

	vector3d* ret = new vector3d(r, theta, phi,vector3d::spherical);
	//ret->xyz();
	return ret;
}

double DataSetTrainer::linear_model(const input_vector& input, const parameter_vector& params) {
	const double p0 = params(0);
	const double p1 = params(1);
	const double p2 = params(2);
	const double p3 = params(3);

	const double i0 = input(0);
	const double i1 = input(1);
	const double i2 = input(2);

	const double temp = p0*i0 + p1*i1 + p2*i2 + p3;

	return temp*temp; //because we're doing least squares
}

double DataSetTrainer::linear_residual(const std::pair<input_vector, double>& data, const parameter_vector& params) {
	return DataSetTrainer::linear_model(data.first, params) - data.second;
}
parameter_vector DataSetTrainer::residual_derivative(const std::pair<input_vector, double>& data, const parameter_vector& params){
	parameter_vector der;

	const double p0 = params(0);
	const double p1 = params(1);
	const double p2 = params(2);
	const double p3 = params(3);

	const double i0 = data.first(0);
	const double i1 = data.first(1);
	const double i2 = data.first(2);

	const double temp = p0*i0 + p1*i1 + p2*i2 + p3;

	der(0) = i0*2*temp;
	der(1) = i1*2*temp;
	der(2) = i2*2*temp;
	der(3) = 2*temp;

	return der;
}

//http://dlib.net/least_squares_ex.cpp.html
void DataSetTrainer::train_linear() {
	//going to need to do this three times. So, you know, will take time.
	std::vector<std::pair<input_vector, double> > data_samples;
	input_vector input;
	//get radius
	for(size_t i = 0; i<this->space->size(); i++){
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2]; //set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi
		data_samples.push_back(std::make_pair(input, vec[0]));//training for creating the radius
	}
	//now get constants
	parameter_vector x;
	x = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::linear_residual,
		dlib::derivative(DataSetTrainer::linear_residual),
		data_samples,
		x);
	//set constants for later use
	this->a = x(0);
	this->b = x(1);
	this->c = x(2);
	this->d = x(3);

	//get theta
	data_samples.clear();
	for(size_t i = 0; i<this->space->size(); i++){
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2];//set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi

		data_samples.push_back(std::make_pair(input, vec[1]));//training for creating the theta
	}
	parameter_vector x1;
	x1 = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::linear_residual,
		dlib::derivative(DataSetTrainer::linear_residual),
		data_samples,
		x1);
	//set constants for later use
	this->e = x1(0);
	this->f = x1(1);
	this->g = x1(2);
	this->h = x1(3);

	//get phi
	data_samples.clear();
	for(size_t i = 0; i<this->space->size(); i++){
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2];//set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi

		data_samples.push_back(std::make_pair(input, vec[2]));//training for creating the phi
	}
	parameter_vector x2;
	x2 = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::linear_residual,
		dlib::derivative(DataSetTrainer::linear_residual),
		data_samples,
		x2);
	//set constants for later use
	this->i = x2(0);
	this->j = x2(1);
	this->k = x2(2);
	this->l = x2(3);
	//AND DONE, FULLY TRAINED. MATHEMATICAL!!!!
}

double DataSetTrainer::hybrid_model(const input_vector& input, const parameter_vector& params) {
	const double p0 = params(0);
	const double p1 = params(1);
	const double p2 = params(2);
	const double p3 = params(3);

	const double i0 = input(0);
	const double i1 = input(1);
	const double i2 = input(2);

	const double temp = p0*i0 + p1*i1 + p2*i2 + p3;

	return temp*temp; //because we're doing least squares
}

double DataSetTrainer::hybrid_residual(const std::pair<input_vector, double>& data, const parameter_vector& params) {
	return DataSetTrainer::linear_model(data.first, params) - data.second;
}

void DataSetTrainer::train_hybrid() {
	//going to need to do this three times. So, you know, will take time.
	std::vector<std::pair<input_vector, double> > data_samples;
	input_vector input;
	//get radius
	for (size_t i = 0; i<this->space->size(); i++) {
		vector3d* vp = this->space->at(i);
		float* pos = vp->xyz();//get data from position
		input = pos[0], pos[1], pos[2]; //set input to be position
		vector3d* vf = this->vectors->at(i);
		float* vec = vf->rtp();//get data from vector, as radius, theta, phi
		data_samples.push_back(std::make_pair(input, vec[0]));//training for creating the radius

		//Neural Net Time
		input_vector pos_iv;
		neural_output vec_no;
		pos_iv(0) = pos[0];
		pos_iv(1) = pos[1];
		pos_iv(2) = pos[2];

		vec_no(0) = (vec[1] / (2 * M_PI))*0.9; //theta range is 0 - 2PI, so we shift down into [0,1] and down again into [0,0.9] to be safe
		vec_no(1) = (vec[2] / M_PI)*0.9; //phi range is 0-PI, so we shift down into [0,1] and down again into [0,0.9] to be safe

		this->net->train(pos_iv, vec_no);//min(vec_no) needs to be >=0.0. UGHHHHH
	}
	//now get constants for R
	parameter_vector x;
	x = 1;
	dlib::solve_least_squares(dlib::objective_delta_stop_strategy(1e-7).be_verbose(),
		DataSetTrainer::hybrid_residual,
		dlib::derivative(DataSetTrainer::hybrid_residual),
		data_samples,
		x);
	//set constants for later use
	this->a = x(0);
	this->b = x(1);
	this->c = x(2);
	this->d = x(3);

}
vector3d* DataSetTrainer::get_from_hybrid(vector3d* loc) {
	//Get R
	float r = (loc->xyz()[0] * this->a) + (loc->xyz()[1] * this->b) + (loc->xyz()[2] * this->c) + this->d;
	//float theta = (loc->xyz()[0] * this->e) + (loc->xyz()[1] * this->f) + (loc->xyz()[2] * this->g) + this->h;
	//float phi = (loc->xyz()[0] * this->i) + (loc->xyz()[1] * this->j) + (loc->xyz()[2] * this->k) + this->l;

	//get THETA, and PHI
	dlib::mlp::kernel_1a_c* net = this->net;
	input_vector in;
	float* arr = loc->xyz();
	in(0) = arr[0];
	in(1) = arr[1];
	in(2) = arr[2];

	neural_output out;
	out = (*net)(in);//don't question the callback-like functionality of objects in c++. I know it's gross, just ignore.

	float theta = (out(0)/0.9) * (2 * M_PI); //shift out from [0,0.9] into [0,1] and then out agin into [0,2PI]
	float phi = (out(1)/0.9) * (M_PI); //shift out from [0,0.9] into [0,1] and then out agin into [0,PI]

	vector3d* ret = new vector3d(r, theta, phi, vector3d::spherical);
	//ret->xyz();
	return ret;
}
<|endoftext|>


<commit_before>#ifndef SLIC3RXS
#include "Config.hpp"
#include "Log.hpp"

namespace Slic3r {

std::shared_ptr<Config>
Config::new_from_defaults()
{
    return std::make_shared<Config>();
}
std::shared_ptr<Config>
Config::new_from_defaults(std::initializer_list<std::string> init)
{
    return Config::new_from_defaults(t_config_option_keys(init));
}

std::shared_ptr<Config>
Config::new_from_defaults(t_config_option_keys init)
{
    auto my_config(std::make_shared<Config>());
    for (auto& opt_key : init) {
        if (print_config_def.has(opt_key)) {
            const std::string value { print_config_def.get(opt_key)->default_value->serialize() };
            my_config->set_deserialize(opt_key, value);
        }
    }

    return my_config;
}

std::shared_ptr<Config>
new_from_cli(const int& argc, const char* argv[])
{
    return std::make_shared<Config>();
}

bool
Config::validate()
{
    return false;
}

void
Config::set(const t_config_option_key& opt_key, const std::string& value)
{
}

void
Config::set(const t_config_option_key& opt_key, const int value)
{
}

void
Config::set(const t_config_option_key& opt_key, const double value)
{
}

void
read_ini(const std::string& file)
{
}

void
write_ini(const std::string& file) const
{
}

} // namespace Slic3r

#endif // SLIC3RXS
<commit_msg>Forgot to add Config:: to methods in Config.cpp<commit_after>#ifndef SLIC3RXS
#include "Config.hpp"
#include "Log.hpp"

namespace Slic3r {

std::shared_ptr<Config>
Config::new_from_defaults()
{
    return std::make_shared<Config>();
}
std::shared_ptr<Config>
Config::new_from_defaults(std::initializer_list<std::string> init)
{
    return Config::new_from_defaults(t_config_option_keys(init));
}

std::shared_ptr<Config>
Config::new_from_defaults(t_config_option_keys init)
{
    auto my_config(std::make_shared<Config>());
    for (auto& opt_key : init) {
        if (print_config_def.has(opt_key)) {
            const std::string value { print_config_def.get(opt_key)->default_value->serialize() };
            my_config->set_deserialize(opt_key, value);
        }
    }

    return my_config;
}

std::shared_ptr<Config>
new_from_cli(const int& argc, const char* argv[])
{
    return std::make_shared<Config>();
}

bool
Config::validate()
{
    return false;
}

void
Config::set(const t_config_option_key& opt_key, const std::string& value)
{
}

void
Config::set(const t_config_option_key& opt_key, const int value)
{
}

void
Config::set(const t_config_option_key& opt_key, const double value)
{
}

void
Config::read_ini(const std::string& file)
{
}

void
Config::write_ini(const std::string& file) const
{
}

} // namespace Slic3r

#endif // SLIC3RXS
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// 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
//
//      https://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 "iree/base/target_platform.h"

#if defined(IREE_PLATFORM_WINDOWS)

#include <io.h>

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "iree/base/file_io.h"
#include "iree/base/file_path.h"
#include "iree/base/internal/file_handle_win32.h"
#include "iree/base/platform_headers.h"
#include "iree/base/tracing.h"

namespace iree {
namespace file_io {

Status FileExists(const std::string& path) {
  IREE_TRACE_SCOPE0("file_io::FileExists");
  DWORD attrs = ::GetFileAttributesA(path.c_str());
  if (attrs == INVALID_FILE_ATTRIBUTES) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to find/access file: " << path;
  }
  return OkStatus();
}

StatusOr<std::string> GetFileContents(const std::string& path) {
  IREE_TRACE_SCOPE0("file_io::GetFileContents");
  ASSIGN_OR_RETURN(auto file, FileHandle::OpenRead(std::move(path),
                                                   FILE_FLAG_SEQUENTIAL_SCAN));
  std::string result;
  result.resize(file->size());
  DWORD bytes_read = 0;
  if (::ReadFile(file->handle(), const_cast<char*>(result.data()),
                 result.size(), &bytes_read, nullptr) == FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to read file span of " << result.size() << " bytes from '"
           << path << "'";
  } else if (bytes_read != file->size()) {
    return ResourceExhaustedErrorBuilder(IREE_LOC)
           << "Unable to read all " << file->size() << " bytes from '" << path
           << "' (got " << bytes_read << ")";
  }
  return result;
}

Status SetFileContents(const std::string& path, absl::string_view content) {
  IREE_TRACE_SCOPE0("file_io::SetFileContents");
  ASSIGN_OR_RETURN(auto file, FileHandle::OpenWrite(std::move(path), 0));
  if (::WriteFile(file->handle(), content.data(), content.size(), NULL, NULL) ==
      FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to write file span of " << content.size() << " bytes to '"
           << path << "'";
  }
  return OkStatus();
}

Status DeleteFile(const std::string& path) {
  IREE_TRACE_SCOPE0("file_io::DeleteFile");
  if (::DeleteFileA(path.c_str()) == FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to delete/access file: " << path;
  }
  return OkStatus();
}

Status MoveFile(const std::string& source_path,
                const std::string& destination_path) {
  IREE_TRACE_SCOPE0("file_io::MoveFile");
  if (::MoveFileA(source_path.c_str(), destination_path.c_str()) == FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to move file " << source_path << " to "
           << destination_path;
  }
  return OkStatus();
}

std::string GetTempPath() {
  IREE_TRACE_SCOPE0("file_io::GetTempPath");

  // TEST_TMPDIR will point to a writeable temp path when running bazel tests.
  char* test_tmpdir = getenv("TEST_TMPDIR");
  if (test_tmpdir) {
    return test_tmpdir;
  }

  std::string temp_path(64, '\0');
  for (bool retry_query = false; retry_query && !temp_path.empty();) {
    DWORD required_length = ::GetTempPathA(temp_path.size(), &temp_path[0]);
    retry_query = required_length > temp_path.size();
    temp_path.resize(required_length);
  }
  return temp_path;
}

StatusOr<std::string> GetTempFile(absl::string_view base_name) {
  IREE_TRACE_SCOPE0("file_io::GetTempFile");

  std::string temp_path = GetTempPath();
  std::string template_path =
      file_path::JoinPaths(temp_path, base_name) + "XXXXXX";

  if (::_mktemp(&template_path[0]) != nullptr) {
    return template_path;  // Should have been modified by _mktemp.
  } else {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to create temp file with template " << template_path;
  }
}

}  // namespace file_io
}  // namespace iree

#endif  // IREE_PLATFORM_WINDOWS
<commit_msg>Fix/simplify loop conditions in Windows GetTempPath.<commit_after>// Copyright 2019 Google LLC
//
// 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
//
//      https://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 "iree/base/target_platform.h"

#if defined(IREE_PLATFORM_WINDOWS)

#include <io.h>

#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "iree/base/file_io.h"
#include "iree/base/file_path.h"
#include "iree/base/internal/file_handle_win32.h"
#include "iree/base/platform_headers.h"
#include "iree/base/tracing.h"

namespace iree {
namespace file_io {

Status FileExists(const std::string& path) {
  IREE_TRACE_SCOPE0("file_io::FileExists");
  DWORD attrs = ::GetFileAttributesA(path.c_str());
  if (attrs == INVALID_FILE_ATTRIBUTES) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to find/access file: " << path;
  }
  return OkStatus();
}

StatusOr<std::string> GetFileContents(const std::string& path) {
  IREE_TRACE_SCOPE0("file_io::GetFileContents");
  ASSIGN_OR_RETURN(auto file, FileHandle::OpenRead(std::move(path),
                                                   FILE_FLAG_SEQUENTIAL_SCAN));
  std::string result;
  result.resize(file->size());
  DWORD bytes_read = 0;
  if (::ReadFile(file->handle(), const_cast<char*>(result.data()),
                 result.size(), &bytes_read, nullptr) == FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to read file span of " << result.size() << " bytes from '"
           << path << "'";
  } else if (bytes_read != file->size()) {
    return ResourceExhaustedErrorBuilder(IREE_LOC)
           << "Unable to read all " << file->size() << " bytes from '" << path
           << "' (got " << bytes_read << ")";
  }
  return result;
}

Status SetFileContents(const std::string& path, absl::string_view content) {
  IREE_TRACE_SCOPE0("file_io::SetFileContents");
  ASSIGN_OR_RETURN(auto file, FileHandle::OpenWrite(std::move(path), 0));
  if (::WriteFile(file->handle(), content.data(), content.size(), NULL, NULL) ==
      FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to write file span of " << content.size() << " bytes to '"
           << path << "'";
  }
  return OkStatus();
}

Status DeleteFile(const std::string& path) {
  IREE_TRACE_SCOPE0("file_io::DeleteFile");
  if (::DeleteFileA(path.c_str()) == FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to delete/access file: " << path;
  }
  return OkStatus();
}

Status MoveFile(const std::string& source_path,
                const std::string& destination_path) {
  IREE_TRACE_SCOPE0("file_io::MoveFile");
  if (::MoveFileA(source_path.c_str(), destination_path.c_str()) == FALSE) {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to move file " << source_path << " to "
           << destination_path;
  }
  return OkStatus();
}

std::string GetTempPath() {
  IREE_TRACE_SCOPE0("file_io::GetTempPath");

  // TEST_TMPDIR will point to a writeable temp path when running bazel tests.
  char* test_tmpdir = getenv("TEST_TMPDIR");
  if (test_tmpdir) {
    return test_tmpdir;
  }

  std::string temp_path(64, '\0');
  for (bool retry_query = true; retry_query;) {
    DWORD required_length = ::GetTempPathA(temp_path.size(), &temp_path[0]);
    retry_query = required_length > temp_path.size();
    temp_path.resize(required_length);
  }
  return temp_path;
}

StatusOr<std::string> GetTempFile(absl::string_view base_name) {
  IREE_TRACE_SCOPE0("file_io::GetTempFile");

  std::string temp_path = GetTempPath();
  std::string template_path =
      file_path::JoinPaths(temp_path, base_name) + "XXXXXX";

  if (::_mktemp(&template_path[0]) != nullptr) {
    return template_path;  // Should have been modified by _mktemp.
  } else {
    return Win32ErrorToCanonicalStatusBuilder(GetLastError(), IREE_LOC)
           << "Unable to create temp file with template " << template_path;
  }
}

}  // namespace file_io
}  // namespace iree

#endif  // IREE_PLATFORM_WINDOWS
<|endoftext|>


<commit_before>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef OLD_CPP
#include "OldConsoleStreambuf.inc"
#else
#include "../include/gnelib/gneintern.h"
#include "../include/gnelib/ConsoleStreambuf.h"
#include "../include/gnelib/Console.h"
#include <streambuf>

namespace GNE {
namespace Console {

//--------------------------------
//
//    ginbuf implementation
//
//--------------------------------
const int IBUF_LEN = 128;

//##ModelId=3BF8444503C9
ginbuf::ginbuf() {
  buf = new char[IBUF_LEN];
  setg(buf, buf + IBUF_LEN, buf + IBUF_LEN);
}

//##ModelId=3BF8444503CA
ginbuf::~ginbuf() {
  delete[] buf;
}

//##ModelId=3BF8444503CB
ginbuf::int_type ginbuf::underflow() {
  //If there is data still in the input buffer, return it.
  if (gptr() < egptr())
    return traits_type::to_int_type(*gptr());

  //else get some more data, and leave room for '\n'
  GNE::Console::getString(buf, IBUF_LEN-2);
  GNE::Console::mputchar('\n'); //Advance the line ourselves, since getString
                                //doesn't.

  //We have to append the newline ourselves
  int x = strlen(buf);
  buf[x] = '\n';
  x++;
  buf[x] = '\0';

  //Set the input buffer to the string read:
  setg(buf, buf, buf + x);

  //Return the next character ready to be read.
  return traits_type::to_int_type(*buf);
}

//--------------------------------
//
//    goutbuf implementation
//
//--------------------------------
const int OBUF_LEN = 256;

//##ModelId=3BF8444503CD
goutbuf::goutbuf() : x(-1), y(-1) {
  buf = new char[OBUF_LEN];
  setp(buf, buf + OBUF_LEN - 1);
  //We want to leave ourselves a character at the end, so that we may null
  //terminate the string during a flush to output a whole string at a time.
}

//##ModelId=3BF8444503CE
goutbuf::~goutbuf() {
  //Actually we don't want to flush, because when this dtor is called we can't
  //output.
  flush_output();
  delete[] buf;
}

//##ModelId=3BF8BBF902E6
void goutbuf::setNextWriteLoc(int xLoc, int yLoc) {
  x = xLoc;
  y = yLoc;
}

//##ModelId=3BF8444503CF
int goutbuf::sync() {
  flush_output();
  return 0;
}

//##ModelId=3BF8444503D0
void goutbuf::flush_output() {
  //We always have a space for the null pointer because we reserved an
  //extra position when we called setp, and we do so again at the end of
  //this function.
  if (pptr() > pbase()) {
    *pptr() = '\0';
    if (x != -1) { //Do a mlprintf if a location was set.
      assert(y != -1);
      Console::mlprintf(x, y, pbase());
      x = y = -1;  //Unset last location.
    } else
      Console::mprintf(pbase());
    setp(buf, buf + OBUF_LEN - 1);
  }
}

//##ModelId=3BF8444503D1
goutbuf::int_type goutbuf::overflow(int_type meta) {
  if (meta != traits_type::eof()) {
    flush_output();
    Console::mputchar(traits_type::to_char_type(meta));
  }
  return traits_type::not_eof(meta);
}

//##ModelId=3BF8444503D3
std::streamsize goutbuf::xsputn(const char_type *ptr, std::streamsize count) {
  for (int i=0; i<count; i++) {
    sputc(ptr[i]);
    if (ptr[i] == '\n')
      flush_output();
  }
  return count;
}

} //namespace Console
} //namespace GNE

#endif //#ifdef OLD_CPP #else
<commit_msg>Made a note of a small bug.<commit_after>/* GNE - Game Networking Engine, a portable multithreaded networking library.
 * Copyright (C) 2001 Jason Winnebeck (gillius@mail.rit.edu)
 * Project website: http://www.rit.edu/~jpw9607/
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifdef OLD_CPP
#include "OldConsoleStreambuf.inc"
#else
#include "../include/gnelib/gneintern.h"
#include "../include/gnelib/ConsoleStreambuf.h"
#include "../include/gnelib/Console.h"
#include <streambuf>

namespace GNE {
namespace Console {

//--------------------------------
//
//    ginbuf implementation
//
//--------------------------------
const int IBUF_LEN = 128;

//##ModelId=3BF8444503C9
ginbuf::ginbuf() {
  buf = new char[IBUF_LEN];
  setg(buf, buf + IBUF_LEN, buf + IBUF_LEN);
}

//##ModelId=3BF8444503CA
ginbuf::~ginbuf() {
  delete[] buf;
}

//##ModelId=3BF8444503CB
ginbuf::int_type ginbuf::underflow() {
  //If there is data still in the input buffer, return it.
  if (gptr() < egptr())
    return traits_type::to_int_type(*gptr());

  //else get some more data, and leave room for '\n'
  GNE::Console::getString(buf, IBUF_LEN-2);
  GNE::Console::mputchar('\n'); //Advance the line ourselves, since getString
                                //doesn't.

  //We have to append the newline ourselves
  int x = strlen(buf);
  buf[x] = '\n';
  x++;
  buf[x] = '\0';

  //Set the input buffer to the string read:
  setg(buf, buf, buf + x);

  //Return the next character ready to be read.
  return traits_type::to_int_type(*buf);
}

//--------------------------------
//
//    goutbuf implementation
//
//--------------------------------
const int OBUF_LEN = 256;

//##ModelId=3BF8444503CD
goutbuf::goutbuf() : x(-1), y(-1) {
  buf = new char[OBUF_LEN];
  setp(buf, buf + OBUF_LEN - 1);
  //We want to leave ourselves a character at the end, so that we may null
  //terminate the string during a flush to output a whole string at a time.
}

//##ModelId=3BF8444503CE
goutbuf::~goutbuf() {
  //Actually we don't want to flush, because when this dtor is called we can't
  //output.
  flush_output();
  delete[] buf;
}

//##ModelId=3BF8BBF902E6
void goutbuf::setNextWriteLoc(int xLoc, int yLoc) {
  x = xLoc;
  y = yLoc;
}

//##ModelId=3BF8444503CF
int goutbuf::sync() {
  flush_output();
  return 0;
}

//##ModelId=3BF8444503D0
/**
 * \bug does not handle nulls in the stream properly in all cases although
 *      most of the time it works.  It seems at least for the case of
 *      a null followed by a newline it ignores the newline.  Other cases
 *      seem to work.
 */
void goutbuf::flush_output() {
  //We always have a space for the null pointer because we reserved an
  //extra position when we called setp, and we do so again at the end of
  //this function.
  if (pptr() > pbase()) {
    *pptr() = '\0';
    if (x != -1) { //Do a mlprintf if a location was set.
      assert(y != -1);
      Console::mlprintf(x, y, pbase());
      x = y = -1;  //Unset last location.
    } else
      Console::mprintf(pbase());
    setp(buf, buf + OBUF_LEN - 1);
  }
}

//##ModelId=3BF8444503D1
goutbuf::int_type goutbuf::overflow(int_type meta) {
  if (meta != traits_type::eof()) {
    flush_output();
    Console::mputchar(traits_type::to_char_type(meta));
  }
  return traits_type::not_eof(meta);
}

//##ModelId=3BF8444503D3
std::streamsize goutbuf::xsputn(const char_type *ptr, std::streamsize count) {
  for (int i=0; i<count; i++) {
    sputc(ptr[i]);
    if (ptr[i] == '\n')
      flush_output();
  }
  return count;
}

} //namespace Console
} //namespace GNE

#endif //#ifdef OLD_CPP #else
<|endoftext|>


<commit_before>
#pragma once

#include "numerics/gradient_descent.hpp"

#include <optional>

#include "geometry/grassmann.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "geometry/symmetric_bilinear_form.hpp"
#include "mathematica/mathematica.hpp"
#include "numerics/hermite3.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace numerics {
namespace internal_gradient_descent {

using geometry::Displacement;
using geometry::InnerProduct;
using geometry::Normalize;
using geometry::R3x3Matrix;
using geometry::SymmetricBilinearForm;
using geometry::SymmetricProduct;
using quantities::Abs;
using quantities::Quotient;
using quantities::Square;
using quantities::si::Kilo;
using quantities::si::Metre;
namespace si = quantities::si;

// The type of Hₖ, which approximates the inverse of the Hessian.
template<typename Scalar, typename Frame>
using InverseHessian =
    SymmetricBilinearForm<Quotient<Square<Length>, Scalar>, Frame, Vector>;

// The line search follows [NW06], algorithms 3.5 and 3.6, which guarantee that
// the chosen step obeys the strong Wolfe conditions.

constexpr double c₁ = 1e-4;
constexpr double c₂ = 0.9;
constexpr double α_max = 1e9;

template<typename Scalar, typename Frame>
double Zoom(double α_lo,
            double α_hi,
            Scalar const& ϕ_0,
            Scalar const& ϕʹ_0,
            Position<Frame> const& x,
            Displacement<Frame> const& p,
            Field<Scalar, Frame> const& f,
            Field<Gradient<Scalar, Frame>, Frame> const& grad_f) {
  auto ϕ_α_lo = f(x + α_lo * p);
  for (;;) {
    auto αⱼ = (α_lo + α_hi) / 2;  ////
    auto const ϕ_αⱼ = f(x + αⱼ * p);
    if (ϕ_αⱼ > ϕ_0 + c₁ * αⱼ * ϕʹ_0 || ϕ_αⱼ >= ϕ_α_lo) {
      α_hi = αⱼ;
    } else {
      auto const ϕʹ_αⱼ = InnerProduct(grad_f(x + αⱼ * p), p);
      if (Abs(ϕʹ_αⱼ) <= -c₂ * ϕʹ_0) {
        return αⱼ;
      }
      if (ϕʹ_αⱼ * (α_hi - α_lo) >= Scalar{}) {
        α_hi = α_lo;
      }
      α_lo = αⱼ;
      ϕ_α_lo = ϕ_αⱼ;
    }
  }
}

template<typename Scalar, typename Frame>
double LineSearch(Position<Frame> const& x,
                  Displacement<Frame> const& p,
                  Field<Scalar, Frame> const& f,
                  Field<Gradient<Scalar, Frame>, Frame> const& grad_f) {
  auto const ϕ_0 = f(x);
  auto const ϕʹ_0 = InnerProduct(grad_f(x), p);
  double αᵢ₋₁ = 0;  // α₀.
  double αᵢ = 1;    // α₁.
  Scalar ϕ_αᵢ₋₁ = ϕ_0;
  Scalar ϕʹ_αᵢ₋₁ = ϕʹ_0;
  while (αᵢ < α_max) {
    auto const ϕ_αᵢ = f(x + αᵢ * p);
    // For i = 1 the second condition implies the first, so it has no effect on
    // the disjuntion (thus, the test on i in [NW06] is unnecessary).
    if (ϕ_αᵢ > ϕ_0 + c₁ * αᵢ * ϕʹ_0 || ϕ_αᵢ >= ϕ_αᵢ₋₁) {
      return Zoom(αᵢ₋₁, αᵢ, ϕ_0, ϕʹ_0, x, p, f, grad_f);
    }
    auto const ϕʹ_αᵢ = InnerProduct(grad_f(x + αᵢ * p), p);
    if (Abs(ϕʹ_αᵢ) <= -c₂ * ϕʹ_0) {
      return αᵢ;
    }
    if (ϕʹ_αᵢ >= Scalar{}) {
      return Zoom(αᵢ, αᵢ₋₁, ϕ_0, ϕʹ_0, x, p, f, grad_f);
    }

    // Cubic interpolation.
    Hermite3<double, Scalar> const hermite3(
        {αᵢ₋₁, αᵢ}, {ϕ_αᵢ₋₁, ϕ_αᵢ}, {ϕʹ_αᵢ₋₁, ϕʹ_αᵢ});

    αᵢ₋₁ = αᵢ;
    ϕ_αᵢ₋₁ = ϕ_αᵢ;
    ϕʹ_αᵢ₋₁ = ϕʹ_αᵢ;

    auto const extrema = hermite3.FindExtrema();
    if (extrema.empty() || extrema.back() <= αᵢ) {
      αᵢ *= 2;
    } else {
      for (double const extremum : extrema) {
        if (extremum > αᵢ) {
          αᵢ = extremum;
          break;
        }
      }
    }
  }
  return αᵢ;
}

// The implementation of BFGS follows [NW06], algorithm 6.18.
template<typename Scalar, typename Frame>
Position<Frame> BroydenFletcherGoldfarbShanno(
    Position<Frame> const& start_position,
    Field<Scalar, Frame> const& f,
    Field<Gradient<Scalar, Frame>, Frame> const& grad_f,
    Length const& tolerance) {
  static SymmetricBilinearForm<double, Frame, Vector> const identity =
      SymmetricBilinearForm<double, Frame, Vector>::Identity();

  mathematica::Logger logger(TEMP_DIR / "gradient_descent.wl");

  // The first step uses vanilla steepest descent.
  auto const x₀ = start_position;
  auto const grad_f_x₀ = grad_f(x₀);

  // We (ab)use the tolerance to determine the first step size.  The assumption
  // is that, if the caller provides a reasonable value then (1) we won't miss
  // "interesting features" of f; (2) the finite differences won't underflow or
  // have other unpleasant properties.
  Displacement<Frame> const p₀ = -Normalize(grad_f_x₀) * tolerance;

  double const α₀ = LineSearch(x₀, p₀, f, grad_f);
  auto const x₁ = x₀+ α₀ * p₀;

  // Special computation of H₀ using eq. 6.20.
  auto const grad_f_x₁ = grad_f(x₁);
  Displacement<Frame> const s₀ = x₁ - x₀;
  auto const y₀ = grad_f_x₁ - grad_f_x₀;
  InverseHessian<Scalar, Frame> const H₀ =
      InnerProduct(s₀, y₀) * identity / y₀.Norm²();

  auto xₖ = x₁;
  auto grad_f_xₖ = grad_f_x₁;
  auto Hₖ = H₀;
  for (;;) {
    logger.Append("grad",
                  std::tuple{xₖ, grad_f_xₖ},
                  mathematica::ExpressIn(quantities::si::Metre));
    logger.Append("inverseHessian",
                  Hₖ,
                  mathematica::ExpressIn(quantities::si::Metre));
    Displacement<Frame> const pₖ = -Hₖ * grad_f_xₖ;
    if (pₖ.Norm() <= tolerance) {
      return xₖ;
    }
    double const αₖ = LineSearch(xₖ, pₖ, f, grad_f);
    auto const xₖ₊₁ = xₖ + αₖ * pₖ;
    auto const grad_f_xₖ₊₁ = grad_f(xₖ₊₁);
    auto const sₖ = xₖ₊₁ - xₖ;
    auto const yₖ = grad_f_xₖ₊₁ - grad_f_xₖ;
    // The formula (6.17) from [NW06] is inconvenient because it uses external
    // products.  Elementary transformations yield the formula below.
    auto const ρ = 1 / InnerProduct(sₖ, yₖ);
    auto const Hₖ₊₁ =
        Hₖ + ρ * ((ρ * Hₖ(yₖ, yₖ) + 1) * SymmetricProduct(sₖ, sₖ) -
                  2 * SymmetricProduct(Hₖ * yₖ, sₖ));

    xₖ = xₖ₊₁;
    grad_f_xₖ = grad_f_xₖ₊₁;
    Hₖ = Hₖ₊₁;
  }
  return xₖ;
}

}  // namespace internal_gradient_descent
}  // namespace numerics
}  // namespace principia
<commit_msg>Interpolation in Zoom.<commit_after>
#pragma once

#include "numerics/gradient_descent.hpp"

#include <optional>

#include "geometry/grassmann.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "geometry/symmetric_bilinear_form.hpp"
#include "mathematica/mathematica.hpp"
#include "numerics/hermite2.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/si.hpp"

namespace principia {
namespace numerics {
namespace internal_gradient_descent {

using geometry::Displacement;
using geometry::InnerProduct;
using geometry::Normalize;
using geometry::R3x3Matrix;
using geometry::SymmetricBilinearForm;
using geometry::SymmetricProduct;
using quantities::Abs;
using quantities::Quotient;
using quantities::Square;
using quantities::si::Kilo;
using quantities::si::Metre;
namespace si = quantities::si;

// The type of Hₖ, which approximates the inverse of the Hessian.
template<typename Scalar, typename Frame>
using InverseHessian =
    SymmetricBilinearForm<Quotient<Square<Length>, Scalar>, Frame, Vector>;

// The line search follows [NW06], algorithms 3.5 and 3.6, which guarantee that
// the chosen step obeys the strong Wolfe conditions.

constexpr double c₁ = 1e-4;
constexpr double c₂ = 0.9;
constexpr double α_multiplier = 2;

template<typename Scalar, typename Frame>
double Zoom(double α_lo,
            double α_hi,
            Scalar ϕ_α_lo,
            Scalar ϕ_α_hi,
            Scalar ϕʹ_α_lo,
            Scalar const& ϕ_0,
            Scalar const& ϕʹ_0,
            Position<Frame> const& x,
            Displacement<Frame> const& p,
            Field<Scalar, Frame> const& f,
            Field<Gradient<Scalar, Frame>, Frame> const& grad_f) {
  for (;;) {
    double αⱼ;
    {
      // Quadratic interpolation.
      Hermite2<Scalar, double> const hermite2(
          {α_lo, α_hi}, {ϕ_α_lo, ϕ_α_hi}, ϕʹ_α_lo);
      auto const α_extremum = hermite2.FindExtremum();
      if (α_lo < α_extremum && α_extremum < α_hi) {
        αⱼ = α_extremum;
      } else {
        // Fall back to bisection.
        αⱼ = (α_lo + α_hi) / 2;
      }
    }

    auto const ϕ_αⱼ = f(x + αⱼ * p);
    if (ϕ_αⱼ > ϕ_0 + c₁ * αⱼ * ϕʹ_0 || ϕ_αⱼ >= ϕ_α_lo) {
      α_hi = αⱼ;
      ϕ_α_hi = ϕ_αⱼ;
    } else {
      auto const ϕʹ_αⱼ = InnerProduct(grad_f(x + αⱼ * p), p);
      if (Abs(ϕʹ_αⱼ) <= -c₂ * ϕʹ_0) {
        return αⱼ;
      }
      if (ϕʹ_αⱼ * (α_hi - α_lo) >= Scalar{}) {
        α_hi = α_lo;
        ϕ_α_hi = ϕ_α_lo;
      }
      α_lo = αⱼ;
      ϕ_α_lo = ϕ_αⱼ;
      ϕʹ_α_lo = ϕʹ_αⱼ;
    }
  }
}

template<typename Scalar, typename Frame>
double LineSearch(Position<Frame> const& x,
                  Displacement<Frame> const& p,
                  Field<Scalar, Frame> const& f,
                  Field<Gradient<Scalar, Frame>, Frame> const& grad_f) {
  auto const ϕ_0 = f(x);
  auto const ϕʹ_0 = InnerProduct(grad_f(x), p);
  double αᵢ₋₁ = 0;  // α₀.
  double αᵢ = 1;    // α₁.
  Scalar ϕ_αᵢ₋₁ = ϕ_0;
  Scalar ϕʹ_αᵢ₋₁ = ϕʹ_0;
  for (;;) {
    auto const ϕ_αᵢ = f(x + αᵢ * p);
    // For i = 1 the second condition implies the first, so it has no effect on
    // the disjuntion (thus, the test on i in [NW06] is unnecessary).
    if (ϕ_αᵢ > ϕ_0 + c₁ * αᵢ * ϕʹ_0 || ϕ_αᵢ >= ϕ_αᵢ₋₁) {
      return Zoom(αᵢ₋₁, αᵢ,
                  ϕ_αᵢ₋₁, ϕ_αᵢ,
                  ϕʹ_αᵢ₋₁,
                  ϕ_0, ϕʹ_0,
                  x, p, f, grad_f);
    }
    auto const ϕʹ_αᵢ = InnerProduct(grad_f(x + αᵢ * p), p);
    if (Abs(ϕʹ_αᵢ) <= -c₂ * ϕʹ_0) {
      return αᵢ;
    }
    if (ϕʹ_αᵢ >= Scalar{}) {
      return Zoom(αᵢ, αᵢ₋₁,
                  ϕ_αᵢ, ϕ_αᵢ₋₁,
                  ϕʹ_αᵢ,
                  ϕ_0, ϕʹ_0,
                  x, p, f, grad_f);
    }

    // We don't have a maximum value of α so we blindly increase it until the
    // conditions are met.
    αᵢ *= α_multiplier;
  }
  return αᵢ;
}

// The implementation of BFGS follows [NW06], algorithm 6.18.
template<typename Scalar, typename Frame>
Position<Frame> BroydenFletcherGoldfarbShanno(
    Position<Frame> const& start_position,
    Field<Scalar, Frame> const& f,
    Field<Gradient<Scalar, Frame>, Frame> const& grad_f,
    Length const& tolerance) {
  static SymmetricBilinearForm<double, Frame, Vector> const identity =
      SymmetricBilinearForm<double, Frame, Vector>::Identity();

  mathematica::Logger logger(TEMP_DIR / "gradient_descent.wl");

  // The first step uses vanilla steepest descent.
  auto const x₀ = start_position;
  auto const grad_f_x₀ = grad_f(x₀);

  // We (ab)use the tolerance to determine the first step size.  The assumption
  // is that, if the caller provides a reasonable value then (1) we won't miss
  // "interesting features" of f; (2) the finite differences won't underflow or
  // have other unpleasant properties.
  Displacement<Frame> const p₀ = -Normalize(grad_f_x₀) * tolerance;

  double const α₀ = LineSearch(x₀, p₀, f, grad_f);
  auto const x₁ = x₀+ α₀ * p₀;

  // Special computation of H₀ using eq. 6.20.
  auto const grad_f_x₁ = grad_f(x₁);
  Displacement<Frame> const s₀ = x₁ - x₀;
  auto const y₀ = grad_f_x₁ - grad_f_x₀;
  InverseHessian<Scalar, Frame> const H₀ =
      InnerProduct(s₀, y₀) * identity / y₀.Norm²();

  auto xₖ = x₁;
  auto grad_f_xₖ = grad_f_x₁;
  auto Hₖ = H₀;
  for (;;) {
    logger.Append("grad",
                  std::tuple{xₖ, grad_f_xₖ},
                  mathematica::ExpressIn(quantities::si::Metre));
    logger.Append("inverseHessian",
                  Hₖ,
                  mathematica::ExpressIn(quantities::si::Metre));
    Displacement<Frame> const pₖ = -Hₖ * grad_f_xₖ;
    if (pₖ.Norm() <= tolerance) {
      return xₖ;
    }
    double const αₖ = LineSearch(xₖ, pₖ, f, grad_f);
    auto const xₖ₊₁ = xₖ + αₖ * pₖ;
    auto const grad_f_xₖ₊₁ = grad_f(xₖ₊₁);
    auto const sₖ = xₖ₊₁ - xₖ;
    auto const yₖ = grad_f_xₖ₊₁ - grad_f_xₖ;
    // The formula (6.17) from [NW06] is inconvenient because it uses external
    // products.  Elementary transformations yield the formula below.
    auto const ρ = 1 / InnerProduct(sₖ, yₖ);
    auto const Hₖ₊₁ =
        Hₖ + ρ * ((ρ * Hₖ(yₖ, yₖ) + 1) * SymmetricProduct(sₖ, sₖ) -
                  2 * SymmetricProduct(Hₖ * yₖ, sₖ));

    xₖ = xₖ₊₁;
    grad_f_xₖ = grad_f_xₖ₊₁;
    Hₖ = Hₖ₊₁;
  }
  return xₖ;
}

}  // namespace internal_gradient_descent
}  // namespace numerics
}  // namespace principia
<|endoftext|>


<commit_before>
#include "../MultiTokenizer.h"
#include "../Stemmer.h"

using namespace std;

enum {
	DISKERROR_STEM_RETURN_ARRAY = 1,
	DISKERROR_STEM_RETURN_BIGRAM
};

Php::Value stem(Php::Parameters &params)
{
	static MultiTokenizer tokenizer;

	string p = params[0];
	tokenizer.SetText(p);
	int prefs = 0;

	if (params.size() > 1) {
		prefs = (int) params[1];
	}

	string outputText, token, thisOne, lastOne;
	static Stemmer stem;
	vector<string> outputArray;

	switch (prefs) {
		case 0:
			while ((token = tokenizer.Get()) != "") {
				outputText += stem(token) + " ";
			}

			if (outputText.size()) {
				outputText.pop_back();    //	remove extra space at end if not empty
			}

			return outputText;

		case DISKERROR_STEM_RETURN_ARRAY:
			while ((token = tokenizer.Get()) != "") {
				outputArray.emplace_back(stem(token));
			}
			return outputArray;

		case DISKERROR_STEM_RETURN_BIGRAM:
			while ((token = tokenizer.Get()) != "") {
				thisOne = stem(token);
				outputText += (lastOne + thisOne + " ");
				lastOne = thisOne;
			}
			outputText += lastOne;
			return outputText;

		case DISKERROR_STEM_RETURN_ARRAY | DISKERROR_STEM_RETURN_BIGRAM:
			while ((token = tokenizer.Get()) != "") {
				thisOne = stem(token);
				outputArray.emplace_back(lastOne + thisOne);
				lastOne = thisOne;
			}
			outputArray.emplace_back(lastOne);
			return outputArray;

		default:
			throw Php::Exception("option does not exist");
	}
}

extern "C" {

    PHPCPP_EXPORT void *get_module()
    {
        // static(!) Php::Extension object that should stay in memory
        // for the entire duration of the process (that's why it's static)
        static Php::Extension extension("diskerror_stem", "0.4");

        extension.add(Php::Constant("DISKERROR_STEM_RETURN_ARRAY", DISKERROR_STEM_RETURN_ARRAY));
        extension.add(Php::Constant("DISKERROR_STEM_RETURN_BIGRAM", DISKERROR_STEM_RETURN_BIGRAM));

		extension.add<stem>( "Diskerror\\Stem", {
        	Php::ByVal("subject", Php::Type::String),
        	Php::ByVal("options", Php::Type::Numeric, false)
        } );

        // return the extension
        return extension;
    }
}
<commit_msg>Update main.cp<commit_after>
#include "../MultiTokenizer.h"
#include "../Stemmer.h"

using namespace std;

enum {
	DISKERROR_STEM_RETURN_ARRAY = 1,
	DISKERROR_STEM_RETURN_BIGRAM
};

Php::Value stem(Php::Parameters &params)
{
	static MultiTokenizer tokenizer;

	string p = params[0];
	tokenizer.SetText(p);
	int prefs = 0;

	if (params.size() > 1) {
		prefs = (int) params[1];
	}

	string outputText, token, thisOne, lastOne;
	static Stemmer stem;
	vector<string> outputArray;

	switch (prefs) {
		case 0:
			while ((token = tokenizer.Get()) != "") {
				outputText += stem(token) + " ";
			}

			if (outputText.size()) {
				outputText.pop_back();    //	remove extra space at end if not empty
			}

			return outputText;

		case DISKERROR_STEM_RETURN_ARRAY:
			while ((token = tokenizer.Get()) != "") {
				outputArray.emplace_back(stem(token));
			}
			return outputArray;

		case DISKERROR_STEM_RETURN_BIGRAM:
			while ((token = tokenizer.Get()) != "") {
				thisOne = stem(token);
				outputText += (lastOne + thisOne + " ");
				lastOne = thisOne;
			}
			outputText += lastOne;
			return outputText;

		case DISKERROR_STEM_RETURN_ARRAY | DISKERROR_STEM_RETURN_BIGRAM:
			while ((token = tokenizer.Get()) != "") {
				thisOne = stem(token);
				outputArray.emplace_back(lastOne + thisOne);
				lastOne = thisOne;
			}
			outputArray.emplace_back(lastOne);
			return outputArray;

		default:
			throw Php::Exception("option does not exist");
	}
}

extern "C" {

    PHPCPP_EXPORT void *get_module()
    {
        // static(!) Php::Extension object that should stay in memory
        // for the entire duration of the process (that's why it's static)
        static Php::Extension extension("diskerror_stem", "0.4");

        extension.add(Php::Constant("DISKERROR_STEM_RETURN_ARRAY", DISKERROR_STEM_RETURN_ARRAY));
        extension.add(Php::Constant("DISKERROR_STEM_RETURN_BIGRAM", DISKERROR_STEM_RETURN_BIGRAM));

		extension.add<stem>( "Diskerror\\stem", {
        	Php::ByVal("subject", Php::Type::String),
        	Php::ByVal("options", Php::Type::Numeric, false)
        } );

        // return the extension
        return extension;
    }
}
<|endoftext|>


<commit_before>// @(#)root/gui:$Id$
// Author: David Gonzalez Maline  21/10/2008

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Tree Input Widget                                                    //
//                                                                      //
// An dialog box that asks the user for the variables and cuts          //
// of the selected tree in the fitpanel.                                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TTreeInput.h"
#include "TGButton.h"
#include "TGLabel.h"
#include "TGTextEntry.h"

enum ETreeInput {
   kTI_TEVARS, kTI_TECUTS
};

ClassImp(TTreeInput)

//______________________________________________________________________________
   TTreeInput::TTreeInput(const TGWindow *p, const TGWindow *main,
                          char *strvars, char *strcuts):
      TGTransientFrame(p, main, 10, 10, kVerticalFrame),
      fStrvars(strvars),
      fStrcuts(strcuts)
{
   // Create simple input dialog.

   if (!p && !main) {
      MakeZombie();
      return;
   }
   SetCleanup(kDeepCleanup);

   TGLabel *label = new TGLabel(this, "Selected Variables: ");
   AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));

   TGTextBuffer *tbuf = new TGTextBuffer(256);  //will be deleted by TGtextEntry
   fTEVars = new TGTextEntry(this, tbuf, kTI_TEVARS);
   fTEVars->Resize(260, fTEVars->GetDefaultHeight());
   AddFrame(fTEVars, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));

   label = new TGLabel(this, "Selected Cuts: ");
   AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));

   tbuf = new TGTextBuffer(256);  //will be deleted by TGtextEntry
   fTECuts = new TGTextEntry(this, tbuf, kTI_TECUTS);
   fTECuts->Resize(260, fTECuts->GetDefaultHeight());
   AddFrame(fTECuts, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));

   // create frame and layout hints for Ok and Cancel buttons
   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 60, 20, kFixedWidth);
   hf->SetCleanup(kDeepCleanup);

   // create OK and Cancel buttons in their own frame (hf)
   UInt_t  width = 0, height = 0;

   fOk = new TGTextButton(hf, "&Ok", 1);
   fOk->Associate(this);
   hf->AddFrame(fOk, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0));
   height = fOk->GetDefaultHeight();
   width  = TMath::Max(width, fOk->GetDefaultWidth());

   fCancel = new TGTextButton(hf, "&Cancel", 2);
   fCancel->Associate(this);
   hf->AddFrame(fCancel, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0));
   height = fCancel->GetDefaultHeight();
   width  = TMath::Max(width, fCancel->GetDefaultWidth());

   // place button frame (hf) at the bottom
   AddFrame(hf, new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 0, 0, 5, 5));

   // keep buttons centered and with the same width
   hf->Resize((width + 20) * 2, height);

   // set dialog title
   SetWindowName("Get Input");

   // map all widgets and calculate size of dialog
   MapSubwindows();

   width  = GetDefaultWidth();
   height = GetDefaultHeight();

   Resize(width, height);

   // position relative to the parent's window
   CenterOnParent();

   // make the message box non-resizable
   SetWMSize(width, height);
   SetWMSizeHints(width, height, width, height, 0, 0);

   SetMWMHints(kMWMDecorAll | kMWMDecorResizeH  | kMWMDecorMaximize |
                                       kMWMDecorMinimize | kMWMDecorMenu,
                        kMWMFuncAll  | kMWMFuncResize    | kMWMFuncMaximize |
                                       kMWMFuncMinimize,
                        kMWMInputModeless);

   // popup dialog and wait till user replies
   MapWindow();
   fTEVars->SetFocus();

   gClient->WaitFor(this);
}

//______________________________________________________________________________
TTreeInput::~TTreeInput()
{
   // Cleanup dialog.

   Cleanup();
}

//______________________________________________________________________________
Bool_t TTreeInput::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
{
   // Handle button and text enter events

   switch (GET_MSG(msg)) {
      case kC_COMMAND:
         switch (GET_SUBMSG(msg)) {
            case kCM_BUTTON:
               switch (parm1) {
                  case 1:
                     // here copy the string from text buffer to return variable
                     strcpy(fStrvars, fTEVars->GetBuffer()->GetString());
                     strcpy(fStrcuts, fTECuts->GetBuffer()->GetString());
                     delete this;
                     break;
                  case 2:
                     fStrvars[0] = 0;
                     fStrcuts[0] = 0;
                     delete this;
                     break;
               }
               default:
                  break;
         }
         break;

      case kC_TEXTENTRY:
         switch (GET_SUBMSG(msg)) {
            case kTE_ENTER:
               // here copy the string from text buffer to return variable
               strcpy(fStrvars, fTEVars->GetBuffer()->GetString());
               strcpy(fStrcuts, fTECuts->GetBuffer()->GetString());
               delete this;
               break;
            case kTE_TAB:
               if ( parm1 == kTI_TEVARS )
                  fTECuts->SetFocus();
               else if ( parm1 == kTI_TECUTS )
                  fTEVars->SetFocus();
               break;
            default:
               break;
         }
         break;

      default:
         break;
   }
   return kTRUE;
}
<commit_msg>Use strncpy instead of strcpy (coverity)<commit_after>// @(#)root/gui:$Id$
// Author: David Gonzalez Maline  21/10/2008

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Tree Input Widget                                                    //
//                                                                      //
// An dialog box that asks the user for the variables and cuts          //
// of the selected tree in the fitpanel.                                //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TTreeInput.h"
#include "TGButton.h"
#include "TGLabel.h"
#include "TGTextEntry.h"

enum ETreeInput {
   kTI_TEVARS, kTI_TECUTS
};

ClassImp(TTreeInput)

//______________________________________________________________________________
   TTreeInput::TTreeInput(const TGWindow *p, const TGWindow *main,
                          char *strvars, char *strcuts):
      TGTransientFrame(p, main, 10, 10, kVerticalFrame),
      fStrvars(strvars),
      fStrcuts(strcuts)
{
   // Create simple input dialog.

   if (!p && !main) {
      MakeZombie();
      return;
   }
   SetCleanup(kDeepCleanup);

   TGLabel *label = new TGLabel(this, "Selected Variables: ");
   AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));

   TGTextBuffer *tbuf = new TGTextBuffer(256);  //will be deleted by TGtextEntry
   fTEVars = new TGTextEntry(this, tbuf, kTI_TEVARS);
   fTEVars->Resize(260, fTEVars->GetDefaultHeight());
   AddFrame(fTEVars, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));

   label = new TGLabel(this, "Selected Cuts: ");
   AddFrame(label, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 0));

   tbuf = new TGTextBuffer(256);  //will be deleted by TGtextEntry
   fTECuts = new TGTextEntry(this, tbuf, kTI_TECUTS);
   fTECuts->Resize(260, fTECuts->GetDefaultHeight());
   AddFrame(fTECuts, new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5));

   // create frame and layout hints for Ok and Cancel buttons
   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 60, 20, kFixedWidth);
   hf->SetCleanup(kDeepCleanup);

   // create OK and Cancel buttons in their own frame (hf)
   UInt_t  width = 0, height = 0;

   fOk = new TGTextButton(hf, "&Ok", 1);
   fOk->Associate(this);
   hf->AddFrame(fOk, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0));
   height = fOk->GetDefaultHeight();
   width  = TMath::Max(width, fOk->GetDefaultWidth());

   fCancel = new TGTextButton(hf, "&Cancel", 2);
   fCancel->Associate(this);
   hf->AddFrame(fCancel, new TGLayoutHints(kLHintsCenterY | kLHintsExpandX, 5, 5, 0, 0));
   height = fCancel->GetDefaultHeight();
   width  = TMath::Max(width, fCancel->GetDefaultWidth());

   // place button frame (hf) at the bottom
   AddFrame(hf, new TGLayoutHints(kLHintsBottom | kLHintsCenterX, 0, 0, 5, 5));

   // keep buttons centered and with the same width
   hf->Resize((width + 20) * 2, height);

   // set dialog title
   SetWindowName("Get Input");

   // map all widgets and calculate size of dialog
   MapSubwindows();

   width  = GetDefaultWidth();
   height = GetDefaultHeight();

   Resize(width, height);

   // position relative to the parent's window
   CenterOnParent();

   // make the message box non-resizable
   SetWMSize(width, height);
   SetWMSizeHints(width, height, width, height, 0, 0);

   SetMWMHints(kMWMDecorAll | kMWMDecorResizeH  | kMWMDecorMaximize |
                                       kMWMDecorMinimize | kMWMDecorMenu,
                        kMWMFuncAll  | kMWMFuncResize    | kMWMFuncMaximize |
                                       kMWMFuncMinimize,
                        kMWMInputModeless);

   // popup dialog and wait till user replies
   MapWindow();
   fTEVars->SetFocus();

   gClient->WaitFor(this);
}

//______________________________________________________________________________
TTreeInput::~TTreeInput()
{
   // Cleanup dialog.

   Cleanup();
}

//______________________________________________________________________________
Bool_t TTreeInput::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
{
   // Handle button and text enter events

   switch (GET_MSG(msg)) {
      case kC_COMMAND:
         switch (GET_SUBMSG(msg)) {
            case kCM_BUTTON:
               switch (parm1) {
                  case 1:
                     // here copy the string from text buffer to return variable
                     // see TFitEditor.cxx for the maximum length:
                     // char variables[256] = {0}; char cuts[256] = {0};
                     strncpy(fStrvars, fTEVars->GetBuffer()->GetString(), 255);
                     strncpy(fStrcuts, fTECuts->GetBuffer()->GetString(), 255);
                     delete this;
                     break;
                  case 2:
                     fStrvars[0] = 0;
                     fStrcuts[0] = 0;
                     delete this;
                     break;
               }
               default:
                  break;
         }
         break;

      case kC_TEXTENTRY:
         switch (GET_SUBMSG(msg)) {
            case kTE_ENTER:
               // here copy the string from text buffer to return variable
               // see TFitEditor.cxx for the maximum length:
               // char variables[256] = {0}; char cuts[256] = {0};
               strncpy(fStrvars, fTEVars->GetBuffer()->GetString(), 255);
               strncpy(fStrcuts, fTECuts->GetBuffer()->GetString(), 255);
               delete this;
               break;
            case kTE_TAB:
               if ( parm1 == kTI_TEVARS )
                  fTECuts->SetFocus();
               else if ( parm1 == kTI_TECUTS )
                  fTEVars->SetFocus();
               break;
            default:
               break;
         }
         break;

      default:
         break;
   }
   return kTRUE;
}
<|endoftext|>


<commit_before><commit_msg>Fix missing brace<commit_after><|endoftext|>


<commit_before>#include <graphics/pipeline/layout.h>
#include <core/video/context.h>
#include <core/log/log.h>

namespace fd {
namespace graphics {
namespace pipeline {

using namespace core;
using namespace video;
using namespace utils;
using namespace log;
using namespace buffer;
using namespace texture;

PipelineLayout::PipelineLayout() : layout(nullptr), descriptorPool(nullptr) {

}

PipelineLayout::~PipelineLayout() {
	for (uint_t i = 0; i < setLayouts.GetSize(); i++) {
		vkDestroyDescriptorSetLayout(Context::GetDevice(), setLayouts[i], nullptr);
	}

	vkDestroyDescriptorPool(Context::GetDevice(), descriptorPool, nullptr);
	vkDestroyPipelineLayout(Context::GetDevice(), layout, nullptr);
}

void PipelineLayout::AddSet(List<PipelineLayoutElement>& elements) {
	VkDescriptorSetLayout setLayout = nullptr;

	if (elements.GetSize() == 0) {
		Log::Warning("[PipelineLayout] No elements!");
		return;
	}

	setOffsets.Push_back(descriptors.GetSize());

	VkDescriptorSetLayoutBinding* bindings = new VkDescriptorSetLayoutBinding[elements.GetSize()];

	for (uint_t i = 0; i < elements.GetSize(); i++) {
		VkDescriptorSetLayoutBinding& b = bindings[i];
		PipelineLayoutElement& e = elements[i];

		b.pImmutableSamplers = nullptr;
		b.binding = e.binding;
		b.stageFlags = e.shaderAccess;
		b.descriptorType = (VkDescriptorType)e.type;
		b.descriptorCount = e.count;

		VkDescriptorPoolSize size;

		size.descriptorCount = e.count;
		size.type = b.descriptorType;

		poolSizes.Push_back(size);

		DescriptorBinding binding;

		binding.type = e.type;
		binding.set = setLayouts.GetSize();
		binding.binding = b.binding;
		binding.count = e.count;
		binding.size = e.size;
		binding.offset = 0;
		binding.texture = nullptr;
		binding.sampler = nullptr;

		descriptors.Push_back(binding);
	}

	VkDescriptorSetLayoutCreateInfo info;

	info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
	info.pNext = nullptr;
	info.flags = 0;
	info.bindingCount = elements.GetSize();
	info.pBindings = bindings;

	VK(vkCreateDescriptorSetLayout(Context::GetDevice(), &info, nullptr, &setLayout));

	setLayouts.Push_back(setLayout);

	delete[] bindings;
}

void PipelineLayout::CreateLayout() {
	VkPipelineLayoutCreateInfo info;

	info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
	info.pNext = nullptr;
	info.flags = 0;
	info.pushConstantRangeCount = 0;
	info.pPushConstantRanges = nullptr;
	info.setLayoutCount = setLayouts.GetSize();
	info.pSetLayouts = setLayouts.GetData();

	VK(vkCreatePipelineLayout(Context::GetDevice(), &info, nullptr, &layout));

	VkDescriptorPoolCreateInfo poolInfo;

	poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
	poolInfo.pNext = nullptr;
	poolInfo.flags = 0;
	poolInfo.maxSets = setLayouts.GetSize();
	poolInfo.poolSizeCount = poolSizes.GetSize();
	poolInfo.pPoolSizes = poolSizes.GetData();

	VK(vkCreateDescriptorPool(Context::GetDevice(), &poolInfo, nullptr, &descriptorPool));

	VkDescriptorSetAllocateInfo allocInfo;

	allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
	allocInfo.pNext = nullptr;
	allocInfo.descriptorPool = descriptorPool;
	allocInfo.descriptorSetCount = setLayouts.GetSize();
	allocInfo.pSetLayouts = setLayouts.GetData();

	descriptorSets.Resize(setLayouts.GetSize());

	VK(vkAllocateDescriptorSets(Context::GetDevice(), &allocInfo, descriptorSets.GetData()));

	uint32 minOffset = Context::GetAdapter()->GetDeviceLimits().minUniformBufferOffsetAlignment;
	uint32 bufferSize = 0;

	for (uint_t i = 0; i< descriptors.GetSize(); i++) {
		DescriptorBinding& b = descriptors[i];

		if (b.type == DescriptorType::Uniform) {
			b.offset = bufferSize;
			bufferSize += b.size >= minOffset ? b.size : minOffset;
		}
	}

	uniformBuffer = new UniformBuffer(nullptr, bufferSize);

	List<VkWriteDescriptorSet> winfo;

	VkDescriptorBufferInfo binfo[1024];

	for (uint_t i = 0; i < descriptors.GetSize(); i++) {
		DescriptorBinding& b = descriptors[i];

		if (b.type == DescriptorType::Uniform) {
			VkWriteDescriptorSet info;

			info.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
			info.pNext = nullptr;
			info.dstSet = descriptorSets[b.set];
			info.dstBinding = b.binding;
			info.descriptorType = (VkDescriptorType)b.type;
			info.descriptorCount = 1;
			info.dstArrayElement = 0;
			info.pTexelBufferView = nullptr;
			info.pImageInfo = nullptr;
			info.pBufferInfo = binfo + i;

			binfo[i].buffer = uniformBuffer->GetBuffer();
			binfo[i].offset = b.offset;
			binfo[i].range = b.size;

			winfo.Push_back(info);
		}
	}

	vkUpdateDescriptorSets(Context::GetDevice(), winfo.GetSize(), winfo.GetData(), 0, nullptr);
}

void PipelineLayout::UpdateUniform(uint32 set, uint32 binding, const void* const data, uint_t size, uint_t offset) {
	DescriptorBinding& b = descriptors[setOffsets[set] + binding];

	if (b.type != DescriptorType::Uniform) {
		Log::Fatal("[PipelineLayout] binding %u in set %u is not a uniform!", binding, set);
		return;
	}

	void* bufferData = uniformBuffer->Map(b.offset + offset, size);
	FD_ASSERT(bufferData != nullptr);
	memcpy(bufferData, data, size);
	uniformBuffer->Unmap();
}

void PipelineLayout::SetTexture(uint32 set, uint32 slots, Texture* texture, Sampler* sampler) {
	SetTexture(set, &slots, 1, texture, sampler);
}

void PipelineLayout::SetTexture(uint32 set, uint32* slots, uint32 num, Texture* textures, Sampler* samplers) {
	VkWriteDescriptorSet* winfo = new VkWriteDescriptorSet[num];

	VkDescriptorImageInfo* iinfo = new VkDescriptorImageInfo[num];

	for (uint32 i = 0; i < num; i++) {
		uint32 slot = slots[i];
		DescriptorBinding& binding = descriptors[setOffsets[set] + slot];

		if (binding.type != DescriptorType::TextureSampler && binding.type != DescriptorType::InputAttachment) {
			Log::Fatal("[PipelineLayout] binding %u in set %u is not a \"TextureSampler\" or \"InputAttachment\"", slot, set);
			break;
		}

		winfo[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
		winfo[i].pNext = nullptr;
		winfo[i].descriptorType = (VkDescriptorType)binding.type;
		winfo[i].dstSet = descriptorSets[set];
		winfo[i].dstBinding = slot;
		winfo[i].dstArrayElement = 0;
		winfo[i].descriptorCount = 1;
		winfo[i].pBufferInfo = nullptr;
		winfo[i].pTexelBufferView = nullptr;

		winfo[i].pImageInfo = iinfo + i;

		iinfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
		iinfo[i].imageView = textures[i].GetImageView();
		binding.texture = textures + i;

		if (binding.type != DescriptorType::TextureSampler) {
			iinfo[i].sampler = samplers[i].GetSampler();
			binding.sampler = samplers + i;
		}
	}

	vkUpdateDescriptorSets(Context::GetDevice(), num, winfo, 0, 0);
}

void PipelineLayout::SetTexture(uint32 set, uint32 slot, VkImageView view) {
	SetTexture(set, &slot, 1, &view);
}

void PipelineLayout::SetTexture(uint32 set, uint32* slots, uint32 num, VkImageView* views) {
	VkWriteDescriptorSet* winfo = new VkWriteDescriptorSet[num];

	VkDescriptorImageInfo* iinfo = new VkDescriptorImageInfo[num];

	for (uint32 i = 0; i < num; i++) {
		uint32 slot = slots[i];
		DescriptorBinding& binding = descriptors[setOffsets[set] + slot];

		if (binding.type != DescriptorType::TextureSampler && binding.type != DescriptorType::InputAttachment) {
			Log::Fatal("[PipelineLayout] binding %u in set %u is not a \"TextureSampler\" or \"InputAttachment\"", slot, set);
			break;
		}

		winfo[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
		winfo[i].pNext = nullptr;
		winfo[i].descriptorType = (VkDescriptorType)binding.type;
		winfo[i].dstSet = descriptorSets[set];
		winfo[i].dstBinding = slot;
		winfo[i].dstArrayElement = 0;
		winfo[i].descriptorCount = 1;
		winfo[i].pBufferInfo = nullptr;
		winfo[i].pTexelBufferView = nullptr;

		winfo[i].pImageInfo = iinfo + i;

		iinfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
		iinfo[i].imageView = views[i];
		iinfo[i].sampler = nullptr;

		binding.texture = nullptr;
		binding.sampler = nullptr;
	}

	vkUpdateDescriptorSets(Context::GetDevice(), num, winfo, 0, 0);
}

}
}
}<commit_msg>VK: Fixed another typo<commit_after>#include <graphics/pipeline/layout.h>
#include <core/video/context.h>
#include <core/log/log.h>

namespace fd {
namespace graphics {
namespace pipeline {

using namespace core;
using namespace video;
using namespace utils;
using namespace log;
using namespace buffer;
using namespace texture;

PipelineLayout::PipelineLayout() : layout(nullptr), descriptorPool(nullptr) {

}

PipelineLayout::~PipelineLayout() {
	for (uint_t i = 0; i < setLayouts.GetSize(); i++) {
		vkDestroyDescriptorSetLayout(Context::GetDevice(), setLayouts[i], nullptr);
	}

	vkDestroyDescriptorPool(Context::GetDevice(), descriptorPool, nullptr);
	vkDestroyPipelineLayout(Context::GetDevice(), layout, nullptr);
}

void PipelineLayout::AddSet(List<PipelineLayoutElement>& elements) {
	VkDescriptorSetLayout setLayout = nullptr;

	if (elements.GetSize() == 0) {
		Log::Warning("[PipelineLayout] No elements!");
		return;
	}

	setOffsets.Push_back(descriptors.GetSize());

	VkDescriptorSetLayoutBinding* bindings = new VkDescriptorSetLayoutBinding[elements.GetSize()];

	for (uint_t i = 0; i < elements.GetSize(); i++) {
		VkDescriptorSetLayoutBinding& b = bindings[i];
		PipelineLayoutElement& e = elements[i];

		b.pImmutableSamplers = nullptr;
		b.binding = e.binding;
		b.stageFlags = e.shaderAccess;
		b.descriptorType = (VkDescriptorType)e.type;
		b.descriptorCount = e.count;

		VkDescriptorPoolSize size;

		size.descriptorCount = e.count;
		size.type = b.descriptorType;

		poolSizes.Push_back(size);

		DescriptorBinding binding;

		binding.type = e.type;
		binding.set = setLayouts.GetSize();
		binding.binding = b.binding;
		binding.count = e.count;
		binding.size = e.size;
		binding.offset = 0;
		binding.texture = nullptr;
		binding.sampler = nullptr;

		descriptors.Push_back(binding);
	}

	VkDescriptorSetLayoutCreateInfo info;

	info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
	info.pNext = nullptr;
	info.flags = 0;
	info.bindingCount = elements.GetSize();
	info.pBindings = bindings;

	VK(vkCreateDescriptorSetLayout(Context::GetDevice(), &info, nullptr, &setLayout));

	setLayouts.Push_back(setLayout);

	delete[] bindings;
}

void PipelineLayout::CreateLayout() {
	VkPipelineLayoutCreateInfo info;

	info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
	info.pNext = nullptr;
	info.flags = 0;
	info.pushConstantRangeCount = 0;
	info.pPushConstantRanges = nullptr;
	info.setLayoutCount = setLayouts.GetSize();
	info.pSetLayouts = setLayouts.GetData();

	VK(vkCreatePipelineLayout(Context::GetDevice(), &info, nullptr, &layout));

	VkDescriptorPoolCreateInfo poolInfo;

	poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
	poolInfo.pNext = nullptr;
	poolInfo.flags = 0;
	poolInfo.maxSets = setLayouts.GetSize();
	poolInfo.poolSizeCount = poolSizes.GetSize();
	poolInfo.pPoolSizes = poolSizes.GetData();

	VK(vkCreateDescriptorPool(Context::GetDevice(), &poolInfo, nullptr, &descriptorPool));

	VkDescriptorSetAllocateInfo allocInfo;

	allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
	allocInfo.pNext = nullptr;
	allocInfo.descriptorPool = descriptorPool;
	allocInfo.descriptorSetCount = setLayouts.GetSize();
	allocInfo.pSetLayouts = setLayouts.GetData();

	descriptorSets.Resize(setLayouts.GetSize());

	VK(vkAllocateDescriptorSets(Context::GetDevice(), &allocInfo, descriptorSets.GetData()));

	uint32 minOffset = Context::GetAdapter()->GetDeviceLimits().minUniformBufferOffsetAlignment;
	uint32 bufferSize = 0;

	for (uint_t i = 0; i< descriptors.GetSize(); i++) {
		DescriptorBinding& b = descriptors[i];

		if (b.type == DescriptorType::Uniform) {
			b.offset = bufferSize;
			bufferSize += b.size >= minOffset ? b.size : minOffset;
		}
	}

	uniformBuffer = new UniformBuffer(nullptr, bufferSize);

	List<VkWriteDescriptorSet> winfo;

	VkDescriptorBufferInfo binfo[1024];

	for (uint_t i = 0; i < descriptors.GetSize(); i++) {
		DescriptorBinding& b = descriptors[i];

		if (b.type == DescriptorType::Uniform) {
			VkWriteDescriptorSet info;

			info.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
			info.pNext = nullptr;
			info.dstSet = descriptorSets[b.set];
			info.dstBinding = b.binding;
			info.descriptorType = (VkDescriptorType)b.type;
			info.descriptorCount = 1;
			info.dstArrayElement = 0;
			info.pTexelBufferView = nullptr;
			info.pImageInfo = nullptr;
			info.pBufferInfo = binfo + i;

			binfo[i].buffer = uniformBuffer->GetBuffer();
			binfo[i].offset = b.offset;
			binfo[i].range = b.size;

			winfo.Push_back(info);
		}
	}

	vkUpdateDescriptorSets(Context::GetDevice(), winfo.GetSize(), winfo.GetData(), 0, nullptr);
}

void PipelineLayout::UpdateUniform(uint32 set, uint32 binding, const void* const data, uint_t size, uint_t offset) {
	DescriptorBinding& b = descriptors[setOffsets[set] + binding];

	if (b.type != DescriptorType::Uniform) {
		Log::Fatal("[PipelineLayout] binding %u in set %u is not a uniform!", binding, set);
		return;
	}

	void* bufferData = uniformBuffer->Map(b.offset + offset, size);
	FD_ASSERT(bufferData != nullptr);
	memcpy(bufferData, data, size);
	uniformBuffer->Unmap();
}

void PipelineLayout::SetTexture(uint32 set, uint32 slots, Texture* texture, Sampler* sampler) {
	SetTexture(set, &slots, 1, texture, sampler);
}

void PipelineLayout::SetTexture(uint32 set, uint32* slots, uint32 num, Texture* textures, Sampler* samplers) {
	VkWriteDescriptorSet* winfo = new VkWriteDescriptorSet[num];

	VkDescriptorImageInfo* iinfo = new VkDescriptorImageInfo[num];

	for (uint32 i = 0; i < num; i++) {
		uint32 slot = slots[i];
		DescriptorBinding& binding = descriptors[setOffsets[set] + slot];

		if (binding.type != DescriptorType::TextureSampler && binding.type != DescriptorType::InputAttachment) {
			Log::Fatal("[PipelineLayout] binding %u in set %u is not a \"TextureSampler\" or \"InputAttachment\"", slot, set);
			break;
		}

		winfo[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
		winfo[i].pNext = nullptr;
		winfo[i].descriptorType = (VkDescriptorType)binding.type;
		winfo[i].dstSet = descriptorSets[set];
		winfo[i].dstBinding = slot;
		winfo[i].dstArrayElement = 0;
		winfo[i].descriptorCount = 1;
		winfo[i].pBufferInfo = nullptr;
		winfo[i].pTexelBufferView = nullptr;

		winfo[i].pImageInfo = iinfo + i;

		iinfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
		iinfo[i].imageView = textures[i].GetImageView();
		binding.texture = textures + i;

		if (binding.type == DescriptorType::TextureSampler) {
			iinfo[i].sampler = samplers[i].GetSampler();
			binding.sampler = samplers + i;
		}
	}

	vkUpdateDescriptorSets(Context::GetDevice(), num, winfo, 0, 0);
}

void PipelineLayout::SetTexture(uint32 set, uint32 slot, VkImageView view) {
	SetTexture(set, &slot, 1, &view);
}

void PipelineLayout::SetTexture(uint32 set, uint32* slots, uint32 num, VkImageView* views) {
	VkWriteDescriptorSet* winfo = new VkWriteDescriptorSet[num];

	VkDescriptorImageInfo* iinfo = new VkDescriptorImageInfo[num];

	for (uint32 i = 0; i < num; i++) {
		uint32 slot = slots[i];
		DescriptorBinding& binding = descriptors[setOffsets[set] + slot];

		if (binding.type != DescriptorType::TextureSampler && binding.type != DescriptorType::InputAttachment) {
			Log::Fatal("[PipelineLayout] binding %u in set %u is not a \"TextureSampler\" or \"InputAttachment\"", slot, set);
			break;
		}

		winfo[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
		winfo[i].pNext = nullptr;
		winfo[i].descriptorType = (VkDescriptorType)binding.type;
		winfo[i].dstSet = descriptorSets[set];
		winfo[i].dstBinding = slot;
		winfo[i].dstArrayElement = 0;
		winfo[i].descriptorCount = 1;
		winfo[i].pBufferInfo = nullptr;
		winfo[i].pTexelBufferView = nullptr;

		winfo[i].pImageInfo = iinfo + i;

		iinfo[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
		iinfo[i].imageView = views[i];
		iinfo[i].sampler = nullptr;

		binding.texture = nullptr;
		binding.sampler = nullptr;
	}

	vkUpdateDescriptorSets(Context::GetDevice(), num, winfo, 0, 0);
}

}
}
}<|endoftext|>