<commit_before>#include "station.h"
#include "ed_info.h"
#include "util.h"

Station::Station(Statement &stmt, ED_Info &info){
	unsigned hasness_bitmap;
	boost::optional<u64> government, allegiance, state, type;
	stmt
		>> this->id
		>> this->system_id
		>> this->name
		>> this->max_landing_pad_size
		>> this->distance_to_star
		>> this->faction
		>> government
		>> allegiance
		>> state
		>> type
		>> hasness_bitmap
		>> this->updated_at
		>> this->shipyard_updated_at;
	this->parse_hasness_bitmap(hasness_bitmap);
	this->government = info.get_government(government);
	this->allegiance = info.get_allegiance(allegiance);
	this->state = info.get_state(state);
	this->type = info.get_station_type(type);
}

Station::Station(const json_value &obj, ED_Info &info){
	SET_MEMBER(id, obj);
	SET_MEMBER(system_id, obj);
	SET_MEMBER(name, obj);
	std::string max_landing_pad_size;
	assign(max_landing_pad_size, obj, "max_landing_pad_size");
	if (max_landing_pad_size == "M")
		this->max_landing_pad_size = 0;
	else if (max_landing_pad_size == "L")
		this->max_landing_pad_size = 1;
	else
		throw std::exception("Invalid data.");
	SET_MEMBER(distance_to_star, obj);
	SET_MEMBER(faction, obj);
	std::string government, allegiance, state, type;
	SET_VARIABLE(government, obj);
	SET_VARIABLE(allegiance, obj);
	SET_VARIABLE(state, obj);
	SET_VARIABLE(type, obj);
	this->government = info.get_government(government);
	this->allegiance = info.get_allegiance(allegiance);
	this->state = info.get_state(state);
	this->type = info.get_station_type(type);
	SET_MEMBER(has_blackmarket, obj);
	SET_MEMBER(has_market, obj);
	SET_MEMBER(has_refuel, obj);
	SET_MEMBER(has_repair, obj);
	SET_MEMBER(has_rearm, obj);
	SET_MEMBER(has_outfitting, obj);
	SET_MEMBER(has_shipyard, obj);
	SET_MEMBER(has_commodities, obj);
	SET_MEMBER(updated_at, obj);
	SET_MEMBER(shipyard_updated_at, obj);
	{
		auto &import_commodities = obj["import_commodities"];
		if (import_commodities.IsArray()){
			auto n = import_commodities.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = import_commodities[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->import_commodities.push_back(info.get_commodity(name));
				}
			}
		}
	}
	{
		auto &export_commodities = obj["export_commodities"];
		if (export_commodities.IsArray()){
			auto n = export_commodities.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = export_commodities[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->export_commodities.push_back(info.get_commodity(name));
				}
			}
		}
	}
	{
		auto &prohibited_commodities = obj["prohibited_commodities"];
		if (prohibited_commodities.IsArray()){
			auto n = prohibited_commodities.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = prohibited_commodities[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->prohibited_commodities.push_back(info.get_commodity(name));
				}
			}
		}
	}
	{
		auto &economies = obj["economies"];
		if (economies.IsArray()){
			auto n = economies.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = economies[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->main_economies.push_back(info.get_economy(name));
				}
			}
		}
	}
	{
		auto &selling_ships = obj["selling_ships"];
		if (selling_ships.IsArray()){
			auto n = selling_ships.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = selling_ships[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->selling_ships.push_back(info.get_ship(name));
				}
			}
		}
	}
	{
		auto &selling_modules = obj["selling_modules"];
		if (selling_modules.IsArray()){
			auto n = selling_modules.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &mod = selling_modules[i];
				u64 id;
				if (mod.IsInt())
					id = selling_modules[i].GetInt();
				else if (mod.IsInt64())
					id = selling_modules[i].GetInt64();
				else
					continue;
				this->selling_modules.push_back(info.modules[id]);
			}
		}
	}
}

void Station::add_extra(Statement &stmt, const ED_Info &info){
	u64 foreign_id;
	int kind;
	stmt >> foreign_id >> kind;
	switch ((StationExtra)kind) {
		case StationExtra::Import:
			this->import_commodities.push_back(info.commodities[foreign_id]);
			break;
		case StationExtra::Export:
			this->export_commodities.push_back(info.commodities[foreign_id]);
			break;
		case StationExtra::Prohibited:
			this->prohibited_commodities.push_back(info.commodities[foreign_id]);
			break;
		case StationExtra::Economy:
			this->main_economies.push_back(info.economies[foreign_id]);
			break;
		case StationExtra::Ship:
			this->selling_ships.push_back(info.ships[foreign_id]);
			break;
		case StationExtra::Module:
			this->selling_modules.push_back(info.modules[foreign_id]);
			break;
	}
}

void Station::add_economy(Statement &stmt, const std::shared_ptr<Commodity> &commodity){
	this->economy.emplace_back(EconomicEntry(stmt, commodity));
	this->economy.back().station = this;
}

EconomicEntry::EconomicEntry(u64 listing[9], const std::shared_ptr<Commodity> &commodity){
	//id,station_id,commodity_id,supply,buy,sell,demand,collected_at,update_count
	this->commodity = commodity;
	int i = 3;
	this->supply = listing[i++];
	this->buy = listing[i++];
	this->sell = listing[i++];
	this->demand = listing[i++];
	this->collected_at = listing[i++];
	this->update_count = listing[i++];
}

void Station::add_economy(u64 listing[9], const std::shared_ptr<Commodity> &commodity){
	this->economy.emplace_back(EconomicEntry(listing, commodity));
	this->economy.back().station = this;
}

const EconomicEntry &Station::find_economic_entry(Commodity *commodity) const{
	for (auto &entry : this->economy)
		if (entry.commodity->id == commodity->id)
			return entry;
	throw std::exception("Cannot find commodity.");
}

unsigned Station::get_hasness_bitmap() const{
	unsigned ret = 0;
	//Order matters!
	const boost::optional<bool> *array[] = {
		&this->has_commodities,
		&this->has_shipyard,
		&this->has_outfitting,
		&this->has_rearm,
		&this->has_repair,
		&this->has_refuel,
		&this->has_market,
		&this->has_blackmarket,
	};

	for (auto p : array){
		ret <<= 2;
		if (!p->is_initialized())
			continue;
		ret |= ((unsigned)p->value() << 1) | 1;
	}
	return ret;
}

void Station::parse_hasness_bitmap(unsigned n){
	//Order matters!
	boost::optional<bool> *array[] = {
		&this->has_blackmarket,
		&this->has_market,
		&this->has_refuel,
		&this->has_repair,
		&this->has_rearm,
		&this->has_outfitting,
		&this->has_shipyard,
		&this->has_commodities,
	};
	for (auto p : array){
		bool is_value = (n & 1) != 0;
		bool value = (n & 2) != 0;
		n >>= 2;
		if (is_value)
			*p = value;
	}
}

void Station::save(
		Statement &new_station,
		Statement &new_extra,
		Statement &new_station_economy){
	new_station
		<< Reset()
		<< this->id
		<< this->system->id
		<< this->name
		<< this->max_landing_pad_size
		<< this->distance_to_star
		<< this->faction;
	BasicStringType *array[] = {
		this->government.get(),
		this->allegiance.get(),
		this->state.get(),
		this->type.get(),
	};
	for (auto p : array){
		if (p)
			new_station << p->id;
		else
			new_station << Null();
	}
	new_station
		<< this->get_hasness_bitmap()
		<< this->updated_at
		<< this->shipyard_updated_at
		<< Step();

	for (auto &commodity : this->import_commodities)
		new_extra
			<< Reset()
			<< this->id
			<< commodity->id
			<< (int)StationExtra::Import
			<< Step();
	for (auto &commodity : this->export_commodities)
		new_extra
			<< Reset()
			<< this->id
			<< commodity->id
			<< (int)StationExtra::Export
			<< Step();
	for (auto &commodity : this->prohibited_commodities)
		new_extra
			<< Reset()
			<< this->id
			<< commodity->id
			<< (int)StationExtra::Prohibited
			<< Step();
	for (auto &econ : this->main_economies)
		new_extra
			<< Reset()
			<< this->id
			<< econ->id
			<< (int)StationExtra::Economy
			<< Step();
	for (auto &ship : this->selling_ships)
		new_extra
			<< Reset()
			<< this->id
			<< ship->id
			<< (int)StationExtra::Ship
			<< Step();
	for (auto &module : this->selling_modules)
		new_extra
			<< Reset()
			<< this->id
			<< module->id
			<< (int)StationExtra::Module
			<< Step();

	for (auto &econ : this->economy){
		new_station_economy
			<< Reset()
			<< this->id
			<< econ.commodity->id
			<< econ.supply
			<< econ.demand
			<< econ.buy
			<< econ.sell
			<< econ.collected_at
			<< econ.update_count
			<< Step();
	}
}

std::shared_ptr<Station> Station::create_virtual_station(StarSystem *system){
	std::shared_ptr<Station> ret(new Station);
	ret->id = std::numeric_limits<decltype(ret->id)>::max();
	ret->system_id = system->id;
	ret->max_landing_pad_size = std::numeric_limits<decltype(ret->max_landing_pad_size)>::max();
	ret->distance_to_star = 0;
	ret->updated_at = 0;
	ret->system = system;
	return ret;
}
<commit_msg>Fixed data import bug.<commit_after>#include "station.h"
#include "ed_info.h"
#include "util.h"

Station::Station(Statement &stmt, ED_Info &info){
	unsigned hasness_bitmap;
	boost::optional<u64> government, allegiance, state, type;
	stmt
		>> this->id
		>> this->system_id
		>> this->name
		>> this->max_landing_pad_size
		>> this->distance_to_star
		>> this->faction
		>> government
		>> allegiance
		>> state
		>> type
		>> hasness_bitmap
		>> this->updated_at
		>> this->shipyard_updated_at;
	this->parse_hasness_bitmap(hasness_bitmap);
	this->government = info.get_government(government);
	this->allegiance = info.get_allegiance(allegiance);
	this->state = info.get_state(state);
	this->type = info.get_station_type(type);
}

Station::Station(const json_value &obj, ED_Info &info){
	SET_MEMBER(id, obj);
	SET_MEMBER(system_id, obj);
	SET_MEMBER(name, obj);
	std::string max_landing_pad_size;
	assign(max_landing_pad_size, obj, "max_landing_pad_size");
	if (max_landing_pad_size == "M")
		this->max_landing_pad_size = 0;
	else if (max_landing_pad_size == "L")
		this->max_landing_pad_size = 1;
	else
		this->max_landing_pad_size = 0;
	SET_MEMBER(distance_to_star, obj);
	SET_MEMBER(faction, obj);
	std::string government, allegiance, state, type;
	SET_VARIABLE(government, obj);
	SET_VARIABLE(allegiance, obj);
	SET_VARIABLE(state, obj);
	SET_VARIABLE(type, obj);
	this->government = info.get_government(government);
	this->allegiance = info.get_allegiance(allegiance);
	this->state = info.get_state(state);
	this->type = info.get_station_type(type);
	SET_MEMBER(has_blackmarket, obj);
	SET_MEMBER(has_market, obj);
	SET_MEMBER(has_refuel, obj);
	SET_MEMBER(has_repair, obj);
	SET_MEMBER(has_rearm, obj);
	SET_MEMBER(has_outfitting, obj);
	SET_MEMBER(has_shipyard, obj);
	SET_MEMBER(has_commodities, obj);
	SET_MEMBER(updated_at, obj);
	SET_MEMBER(shipyard_updated_at, obj);
	{
		auto &import_commodities = obj["import_commodities"];
		if (import_commodities.IsArray()){
			auto n = import_commodities.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = import_commodities[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->import_commodities.push_back(info.get_commodity(name));
				}
			}
		}
	}
	{
		auto &export_commodities = obj["export_commodities"];
		if (export_commodities.IsArray()){
			auto n = export_commodities.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = export_commodities[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->export_commodities.push_back(info.get_commodity(name));
				}
			}
		}
	}
	{
		auto &prohibited_commodities = obj["prohibited_commodities"];
		if (prohibited_commodities.IsArray()){
			auto n = prohibited_commodities.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = prohibited_commodities[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->prohibited_commodities.push_back(info.get_commodity(name));
				}
			}
		}
	}
	{
		auto &economies = obj["economies"];
		if (economies.IsArray()){
			auto n = economies.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = economies[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->main_economies.push_back(info.get_economy(name));
				}
			}
		}
	}
	{
		auto &selling_ships = obj["selling_ships"];
		if (selling_ships.IsArray()){
			auto n = selling_ships.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &val = selling_ships[i];
				if (val.IsString()){
					std::string name = val.GetString();
					this->selling_ships.push_back(info.get_ship(name));
				}
			}
		}
	}
	{
		auto &selling_modules = obj["selling_modules"];
		if (selling_modules.IsArray()){
			auto n = selling_modules.Size();
			for (decltype(n) i = 0; i < n; i++){
				auto &mod = selling_modules[i];
				u64 id;
				if (mod.IsInt())
					id = selling_modules[i].GetInt();
				else if (mod.IsInt64())
					id = selling_modules[i].GetInt64();
				else
					continue;
				this->selling_modules.push_back(info.modules[id]);
			}
		}
	}
}

void Station::add_extra(Statement &stmt, const ED_Info &info){
	u64 foreign_id;
	int kind;
	stmt >> foreign_id >> kind;
	switch ((StationExtra)kind) {
		case StationExtra::Import:
			this->import_commodities.push_back(info.commodities[foreign_id]);
			break;
		case StationExtra::Export:
			this->export_commodities.push_back(info.commodities[foreign_id]);
			break;
		case StationExtra::Prohibited:
			this->prohibited_commodities.push_back(info.commodities[foreign_id]);
			break;
		case StationExtra::Economy:
			this->main_economies.push_back(info.economies[foreign_id]);
			break;
		case StationExtra::Ship:
			this->selling_ships.push_back(info.ships[foreign_id]);
			break;
		case StationExtra::Module:
			this->selling_modules.push_back(info.modules[foreign_id]);
			break;
	}
}

void Station::add_economy(Statement &stmt, const std::shared_ptr<Commodity> &commodity){
	this->economy.emplace_back(EconomicEntry(stmt, commodity));
	this->economy.back().station = this;
}

EconomicEntry::EconomicEntry(u64 listing[9], const std::shared_ptr<Commodity> &commodity){
	//id,station_id,commodity_id,supply,buy,sell,demand,collected_at,update_count
	this->commodity = commodity;
	int i = 3;
	this->supply = listing[i++];
	this->buy = listing[i++];
	this->sell = listing[i++];
	this->demand = listing[i++];
	this->collected_at = listing[i++];
	this->update_count = listing[i++];
}

void Station::add_economy(u64 listing[9], const std::shared_ptr<Commodity> &commodity){
	this->economy.emplace_back(EconomicEntry(listing, commodity));
	this->economy.back().station = this;
}

const EconomicEntry &Station::find_economic_entry(Commodity *commodity) const{
	for (auto &entry : this->economy)
		if (entry.commodity->id == commodity->id)
			return entry;
	throw std::exception("Cannot find commodity.");
}

unsigned Station::get_hasness_bitmap() const{
	unsigned ret = 0;
	//Order matters!
	const boost::optional<bool> *array[] = {
		&this->has_commodities,
		&this->has_shipyard,
		&this->has_outfitting,
		&this->has_rearm,
		&this->has_repair,
		&this->has_refuel,
		&this->has_market,
		&this->has_blackmarket,
	};

	for (auto p : array){
		ret <<= 2;
		if (!p->is_initialized())
			continue;
		ret |= ((unsigned)p->value() << 1) | 1;
	}
	return ret;
}

void Station::parse_hasness_bitmap(unsigned n){
	//Order matters!
	boost::optional<bool> *array[] = {
		&this->has_blackmarket,
		&this->has_market,
		&this->has_refuel,
		&this->has_repair,
		&this->has_rearm,
		&this->has_outfitting,
		&this->has_shipyard,
		&this->has_commodities,
	};
	for (auto p : array){
		bool is_value = (n & 1) != 0;
		bool value = (n & 2) != 0;
		n >>= 2;
		if (is_value)
			*p = value;
	}
}

void Station::save(
		Statement &new_station,
		Statement &new_extra,
		Statement &new_station_economy){
	new_station
		<< Reset()
		<< this->id
		<< this->system->id
		<< this->name
		<< this->max_landing_pad_size
		<< this->distance_to_star
		<< this->faction;
	BasicStringType *array[] = {
		this->government.get(),
		this->allegiance.get(),
		this->state.get(),
		this->type.get(),
	};
	for (auto p : array){
		if (p)
			new_station << p->id;
		else
			new_station << Null();
	}
	new_station
		<< this->get_hasness_bitmap()
		<< this->updated_at
		<< this->shipyard_updated_at
		<< Step();

	for (auto &commodity : this->import_commodities)
		new_extra
			<< Reset()
			<< this->id
			<< commodity->id
			<< (int)StationExtra::Import
			<< Step();
	for (auto &commodity : this->export_commodities)
		new_extra
			<< Reset()
			<< this->id
			<< commodity->id
			<< (int)StationExtra::Export
			<< Step();
	for (auto &commodity : this->prohibited_commodities)
		new_extra
			<< Reset()
			<< this->id
			<< commodity->id
			<< (int)StationExtra::Prohibited
			<< Step();
	for (auto &econ : this->main_economies)
		new_extra
			<< Reset()
			<< this->id
			<< econ->id
			<< (int)StationExtra::Economy
			<< Step();
	for (auto &ship : this->selling_ships)
		new_extra
			<< Reset()
			<< this->id
			<< ship->id
			<< (int)StationExtra::Ship
			<< Step();
	for (auto &module : this->selling_modules)
		new_extra
			<< Reset()
			<< this->id
			<< module->id
			<< (int)StationExtra::Module
			<< Step();

	for (auto &econ : this->economy){
		new_station_economy
			<< Reset()
			<< this->id
			<< econ.commodity->id
			<< econ.supply
			<< econ.demand
			<< econ.buy
			<< econ.sell
			<< econ.collected_at
			<< econ.update_count
			<< Step();
	}
}

std::shared_ptr<Station> Station::create_virtual_station(StarSystem *system){
	std::shared_ptr<Station> ret(new Station);
	ret->id = std::numeric_limits<decltype(ret->id)>::max();
	ret->system_id = system->id;
	ret->max_landing_pad_size = std::numeric_limits<decltype(ret->max_landing_pad_size)>::max();
	ret->distance_to_star = 0;
	ret->updated_at = 0;
	ret->system = system;
	return ret;
}
<|endoftext|>


<commit_before>/*
 * File:   BackpropeagationLearner.cpp
 * Author: janvojt
 *
 * Created on July 13, 2014, 12:10 AM
 */

#include "BackpropagationLearner.h"
#include "Network.h"
#include "LabeledDataset.h"
#include <cstring>
#include <string>
#include <stdexcept>

#include "log/LoggerFactory.h"
#include "log4cpp/Category.hh"

BackpropagationLearner::BackpropagationLearner(Network *network) {
    this->network = network;
    learningRate = 1;
    epochCounter = 0;
    epochLimit = 1000000;
    targetMse = .0001;
    errorTotal = std::numeric_limits<double>::infinity();
    allocateCache();
}

BackpropagationLearner::BackpropagationLearner(const BackpropagationLearner &orig) {
}

BackpropagationLearner::~BackpropagationLearner() {

}

void BackpropagationLearner::allocateCache() {
    weightDiffs = new double[network->getWeightsOffset(network->getConfiguration()->getLayers())];
    localGradients = new double[network->getAllNeurons()];

    useBias = network->getConfiguration()->getBias();
    biasDiff = useBias ? new double[network->getAllNeurons()] : NULL;
}

void BackpropagationLearner::train(LabeledDataset *dataset) {
    double mse;
    LOG()->info("Started training with limits of %d epochs and target MSE of %f.", epochLimit, targetMse);
    do {
        epochCounter++;
        LOG()->debug("Starting epoch %d.", epochCounter);
        dataset->reset();
        int datasetSize = 0;
        mse = 0;
        while (dataset->hasNext()) {
            datasetSize++;
            double *pattern = dataset->next();
            double *expOutput = pattern + dataset->getInputDimension();
            LOG()->debug("Learning pattern [%f, %f] -> [%f].", pattern[0], pattern[1], expOutput[0]);
            doForwardPhase(pattern);
            doBackwardPhase(expOutput);
            mse += errorComputer->compute(network, expOutput);
        }
        mse = mse / datasetSize;
        LOG()->debug("Finished epoch %d with MSE: %f.", epochCounter, mse);
    } while (mse > targetMse && epochCounter < epochLimit);
    LOG()->info("Finished training after %d epochs with MSE of %f.", epochCounter, mse);
}

void BackpropagationLearner::doForwardPhase(double *input) {
    network->setInput(input);
    network->run();
}

void BackpropagationLearner::doBackwardPhase(double *expectedOutput) {
    computeOutputGradients(expectedOutput);
    computeWeightDifferentials();
    adjustWeights();
    if (network->getConfiguration()->getBias()) {
        adjustBias();
    }
}

void BackpropagationLearner::computeOutputGradients(double *expectedOutput) {
    int on = network->getOutputNeurons();
    int noLayers = network->getConfiguration()->getLayers();
    double *localGradient = localGradients + network->getPotentialOffset(noLayers-1);
    double *output = network->getOutput();
    void (*daf) (double*,double*,int) = network->getConfiguration()->dActivationFnc;

    // compute local gradients
    double *dv = new double[network->getOutputNeurons()];
    daf(network->getPotentialValues() + network->getPotentialOffset(noLayers-1), dv, on);
    for (int i = 0; i<on; i++) {
        localGradient[i] = (output[i] - expectedOutput[i]) * dv[i];
    }
}

void BackpropagationLearner::computeWeightDifferentials() {
    int noLayers = network->getConfiguration()->getLayers();
    void (*daf) (double*,double*,int) = network->getConfiguration()->dActivationFnc;

    for (int l = noLayers-1; l>0; l--) {

        // INITIALIZE HELPER VARIABLES
        int thisPotentialIndex = network->getPotentialOffset(l-1);
        double *thisLocalGradient = localGradients + thisPotentialIndex;
        int nextPotentialIndex = network->getPotentialOffset(l);
        double *nextLocalGradient = localGradients + nextPotentialIndex;
        int thisNeurons = network->getConfiguration()->getNeurons(l-1);
        int nextNeurons = network->getConfiguration()->getNeurons(l);
        double *thisPotential = network->getPotentialValues() + thisPotentialIndex;
        double *weights = network->getWeights() + network->getWeightsOffset(l-1);

        // COMPUTE TOTAL DERIVATIVES for weights between layer l and l+1
        int wc = network->getWeightsOffset(l+1) - network->getWeightsOffset(l);
        double *thisInputs = network->getInputValues() + network->getPotentialOffset(l-1);
        double *wdiff = weightDiffs + network->getWeightsOffset(l);
        for (int i = 0; i<wc; i++) {
            wdiff[i] = -learningRate * nextLocalGradient[i%nextNeurons] * thisInputs[i/nextNeurons];
        }

        // COMPUTE BIAS DERIVATIVES for layer l+1
        if (useBias) {
            for (int i = 0; i<nextNeurons; i++) {
                biasDiff[nextPotentialIndex + i] = -learningRate * nextLocalGradient[i];
            }
        }

        // COMPUTE LOCAL GRADIENTS for layer l

        // compute derivatives of neuron potentials in layer l
        double *thisPotentialDerivatives = new double[thisNeurons];
        daf(thisPotential, thisPotentialDerivatives, thisNeurons);

        // compute local gradients for layer l
        for (int i = 0; i<thisNeurons; i++) {
            double sumNextGradient = 0;
            for (int j = 0; j<nextNeurons; j++) {
                sumNextGradient += nextLocalGradient[j] * weights[i * thisNeurons + j];
            }
            thisLocalGradient[i] = sumNextGradient * thisPotentialDerivatives[i];
        }
    }
}

void BackpropagationLearner::adjustWeights() {
    int wc = network->getWeightsOffset(network->getConfiguration()->getLayers());
    double *weights = network->getWeights();
    LOG()->debug("Adjusting weights by: [[%f, %f, %f, %f], [%f, %f]].", weightDiffs[2], weightDiffs[3], weightDiffs[4], weightDiffs[5], weightDiffs[6], weightDiffs[7]);
    // we should skip the garbage in zero-layer weights
    for(int i = network->getWeightsOffset(1); i<wc; i++) {
        weights[i] += weightDiffs[i];
    }
}

void BackpropagationLearner::adjustBias() {
    double *bias = network->getBiasValues();
    int noNeurons = network->getAllNeurons();
    for (int i = 0; i<noNeurons; i++) {
        bias[i] += biasDiff[i];
    }
}

void BackpropagationLearner::clearLayer(double *inputPtr, int layerSize) {
    std::fill_n(inputPtr, layerSize, 0);
}

void BackpropagationLearner::validate(LabeledDataset *dataset) {
    if (dataset->getInputDimension() != network->getInputNeurons()) {
        throw new std::invalid_argument("Provided dataset must have the same input dimension as the number of input neurons!");
    }
    if (dataset->getOutputDimension() != network->getOutputNeurons()) {
        throw new std::invalid_argument("Provided dataset must have the same output dimension as the number of output neurons!");
    }
}

void BackpropagationLearner::setEpochLimit(int limit) {
    epochLimit = limit;
}

void BackpropagationLearner::setErrorComputer(ErrorComputer* errorComputer) {
    this->errorComputer = errorComputer;
}

void BackpropagationLearner::setTargetMse(double mse) {
    targetMse = mse;
}
<commit_msg>Fixed weight indexing in BP learner.<commit_after>/*
 * File:   BackpropeagationLearner.cpp
 * Author: janvojt
 *
 * Created on July 13, 2014, 12:10 AM
 */

#include "BackpropagationLearner.h"
#include "Network.h"
#include "LabeledDataset.h"
#include <cstring>
#include <string>
#include <stdexcept>

#include "log/LoggerFactory.h"
#include "log4cpp/Category.hh"

BackpropagationLearner::BackpropagationLearner(Network *network) {
    this->network = network;
    learningRate = 1;
    epochCounter = 0;
    epochLimit = 1000000;
    targetMse = .0001;
    errorTotal = std::numeric_limits<double>::infinity();
    allocateCache();
}

BackpropagationLearner::BackpropagationLearner(const BackpropagationLearner &orig) {
}

BackpropagationLearner::~BackpropagationLearner() {

}

void BackpropagationLearner::allocateCache() {
    weightDiffs = new double[network->getWeightsOffset(network->getConfiguration()->getLayers())];
    localGradients = new double[network->getAllNeurons()];

    useBias = network->getConfiguration()->getBias();
    biasDiff = useBias ? new double[network->getAllNeurons()] : NULL;
}

void BackpropagationLearner::train(LabeledDataset *dataset) {
    double mse;
    LOG()->info("Started training with limits of %d epochs and target MSE of %f.", epochLimit, targetMse);
    do {
        epochCounter++;
        LOG()->debug("Starting epoch %d.", epochCounter);
        dataset->reset();
        int datasetSize = 0;
        mse = 0;
        while (dataset->hasNext()) {
            datasetSize++;
            double *pattern = dataset->next();
            double *expOutput = pattern + dataset->getInputDimension();
            LOG()->debug("Learning pattern [%f, %f] -> [%f].", pattern[0], pattern[1], expOutput[0]);
            doForwardPhase(pattern);
            doBackwardPhase(expOutput);
            mse += errorComputer->compute(network, expOutput);
        }
        mse = mse / datasetSize;
        LOG()->debug("Finished epoch %d with MSE: %f.", epochCounter, mse);
    } while (mse > targetMse && epochCounter < epochLimit);
    LOG()->info("Finished training after %d epochs with MSE of %f.", epochCounter, mse);
}

void BackpropagationLearner::doForwardPhase(double *input) {
    network->setInput(input);
    network->run();
}

void BackpropagationLearner::doBackwardPhase(double *expectedOutput) {
    computeOutputGradients(expectedOutput);
    computeWeightDifferentials();
    adjustWeights();
    if (network->getConfiguration()->getBias()) {
        adjustBias();
    }
}

void BackpropagationLearner::computeOutputGradients(double *expectedOutput) {
    int on = network->getOutputNeurons();
    int noLayers = network->getConfiguration()->getLayers();
    double *localGradient = localGradients + network->getPotentialOffset(noLayers-1);
    double *output = network->getOutput();
    void (*daf) (double*,double*,int) = network->getConfiguration()->dActivationFnc;

    // compute local gradients
    double *dv = new double[network->getOutputNeurons()];
    daf(network->getPotentialValues() + network->getPotentialOffset(noLayers-1), dv, on);
    for (int i = 0; i<on; i++) {
        localGradient[i] = (output[i] - expectedOutput[i]) * dv[i];
    }
}

void BackpropagationLearner::computeWeightDifferentials() {
    int noLayers = network->getConfiguration()->getLayers();
    void (*daf) (double*,double*,int) = network->getConfiguration()->dActivationFnc;

    for (int l = noLayers-1; l>0; l--) {

        // INITIALIZE HELPER VARIABLES
        int thisPotentialIndex = network->getPotentialOffset(l-1);
        double *thisLocalGradient = localGradients + thisPotentialIndex;
        int nextPotentialIndex = network->getPotentialOffset(l);
        double *nextLocalGradient = localGradients + nextPotentialIndex;
        int thisNeurons = network->getConfiguration()->getNeurons(l-1);
        int nextNeurons = network->getConfiguration()->getNeurons(l);
        double *thisPotential = network->getPotentialValues() + thisPotentialIndex;
        double *weights = network->getWeights() + network->getWeightsOffset(l-1);

        // COMPUTE TOTAL DERIVATIVES for weights between layer l and l+1
        int wc = network->getWeightsOffset(l+1) - network->getWeightsOffset(l) + 1;
        double *thisInputs = network->getInputValues() + network->getPotentialOffset(l-1);
        double *wdiff = weightDiffs + network->getWeightsOffset(l);
        for (int i = 0; i<wc; i++) {
            wdiff[i] = -learningRate * nextLocalGradient[i%nextNeurons] * thisInputs[i/nextNeurons];
        }

        // COMPUTE BIAS DERIVATIVES for layer l+1
        if (useBias) {
            for (int i = 0; i<nextNeurons; i++) {
                biasDiff[nextPotentialIndex + i] = -learningRate * nextLocalGradient[i];
            }
        }

        // COMPUTE LOCAL GRADIENTS for layer l

        // compute derivatives of neuron potentials in layer l
        double *thisPotentialDerivatives = new double[thisNeurons];
        daf(thisPotential, thisPotentialDerivatives, thisNeurons);

        // compute local gradients for layer l
        for (int i = 0; i<thisNeurons; i++) {
            double sumNextGradient = 0;
            for (int j = 0; j<nextNeurons; j++) {
                sumNextGradient += nextLocalGradient[j] * weights[i * thisNeurons + j];
            }
            thisLocalGradient[i] = sumNextGradient * thisPotentialDerivatives[i];
        }
    }
}

void BackpropagationLearner::adjustWeights() {
    int wc = network->getWeightsOffset(network->getConfiguration()->getLayers()) + 1;
    double *weights = network->getWeights();
    LOG()->debug("Adjusting weights by: [[%f, %f, %f], [%f, %f, %f], [%f, %f, %f]].",
            weightDiffs[2], weightDiffs[3], weightDiffs[4],
            weightDiffs[5], weightDiffs[6], weightDiffs[7], weightDiffs[8],
            weightDiffs[9], weightDiffs[10]);

    // we should skip the garbage in zero-layer weights
    for(int i = network->getWeightsOffset(1); i<wc; i++) {
        weights[i] += weightDiffs[i];
    }
}

void BackpropagationLearner::adjustBias() {
    double *bias = network->getBiasValues();
    int noNeurons = network->getAllNeurons();
    for (int i = 0; i<noNeurons; i++) {
        bias[i] += biasDiff[i];
    }
}

void BackpropagationLearner::clearLayer(double *inputPtr, int layerSize) {
    std::fill_n(inputPtr, layerSize, 0);
}

void BackpropagationLearner::validate(LabeledDataset *dataset) {
    if (dataset->getInputDimension() != network->getInputNeurons()) {
        throw new std::invalid_argument("Provided dataset must have the same input dimension as the number of input neurons!");
    }
    if (dataset->getOutputDimension() != network->getOutputNeurons()) {
        throw new std::invalid_argument("Provided dataset must have the same output dimension as the number of output neurons!");
    }
}

void BackpropagationLearner::setEpochLimit(int limit) {
    epochLimit = limit;
}

void BackpropagationLearner::setErrorComputer(ErrorComputer* errorComputer) {
    this->errorComputer = errorComputer;
}

void BackpropagationLearner::setTargetMse(double mse) {
    targetMse = mse;
}
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <ros/console.h>
#include <sensor_msgs/PointCloud2.h>
// PCL specific includes
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>

ros::Publisher pub_v; // voxel publisher
ros::Publisher pub_p;
ros::Publisher pub_f;
// How to avoid hard-coding a topic name?
ros::Publisher pub_c; // publish cluster

void cloud_cb(const sensor_msgs::PointCloud2ConstPtr& input) {
  // Container for original & filtered data
  pcl::PCLPointCloud2* cloud = new pcl::PCLPointCloud2;
  pcl::PCLPointCloud2ConstPtr cloudPtr(cloud);
  pcl::PCLPointCloud2 cloud_filtered; // (new pcl::PCLPointCloud2);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_templated (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_p (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_f (new pcl::PointCloud<pcl::PointXYZ>);
  pcl_conversions::toPCL(*input, *cloud);

  // StatOutlierRemoval
  // How to use both of SOR and VG?
  /* pcl::StatisticalOutlierRemoval<pcl::PCLPointCloud2> sor_0;
  sor_0.setInputCloud(cloudPtr);
  sor_0.setMeanK(50);
  sor_0.setStddevMulThresh(1.0);
  sor_0.filter(cloud_filtered); // fill in an empty variable */

  // Downsampling
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud(cloudPtr);
  sor.setLeafSize(0.02f, 0.02f, 0.02f);
  sor.filter(cloud_filtered);

  // Publishing voxel
  sensor_msgs::PointCloud2 output_v;
  pcl_conversions::fromPCL(cloud_filtered, output_v);
  pub_v.publish(output_v);

  // Convert
  pcl::fromPCLPointCloud2(cloud_filtered, *cloud_templated); // unused

  /* Perform the actual filtering */
  // Create the segmentation object
  pcl::SACSegmentation<pcl::PointXYZ> seg;
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  seg.setOptimizeCoefficients (true); // Optional
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (1000); // added
  seg.setDistanceThreshold (0.02);

  /* Filtering Object: Extraction */
  // pcl::ExtractIndices<pcl::PointXYZ> extract;

  int i = 0, nr_points = (int) cloud_templated->points.size ();
  // While 30% of the original cloud is still there
  while (cloud_templated->points.size () > 0.3 * nr_points)
    {
      // Segment the largest planar component from the remaining cloud
      seg.setInputCloud (cloud_templated);
      seg.segment (*inliers, *coefficients);
      if (inliers->indices.size () == 0)
        {
          ROS_INFO("Could not estimate a planar model for the given dataset.");
          break;
        }

      // Extract the inliers
      pcl::ExtractIndices<pcl::PointXYZ> extract;
      extract.setInputCloud (cloud_templated);
      extract.setIndices (inliers);
      extract.setNegative (false);

      // Get the points associated with the planar surface
      extract.filter (*cloud_p);

      // Remove the planar inliers, extract the rest
      extract.setNegative (true);
      extract.filter (*cloud_f);
      *cloud_templated = *cloud_f;
      // cloud_templated.swap (cloud_f);
      i++;
    }

  // Creating the KdTree object for the search method of the extraction
  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
  tree->setInputCloud (cloud_templated);

  std::vector<pcl::PointIndices> cluster_indices;
  pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
  ec.setClusterTolerance (0.02); // 0.02 = 2ch
  ec.setMinClusterSize (100); // parameter
  ec.setMaxClusterSize (25000); // parameter
  ec.setSearchMethod (tree);
  ec.setInputCloud (cloud_templated);
  ec.extract (cluster_indices);

  int j = 0;
  for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin ();
       it != cluster_indices.end (); ++it) {
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
      for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++)
        cloud_cluster->points.push_back (cloud_templated->points[*pit]); //*
      cloud_cluster->width = cloud_cluster->points.size ();
      cloud_cluster->height = 1;
      cloud_cluster->is_dense = true;

      // Convert data type and publish, but not sure which cluster is published!
      pcl::PCLPointCloud2 out_c;
      sensor_msgs::PointCloud2 output_c;
      pcl::toPCLPointCloud2(*cloud_cluster, out_c);
      pcl_conversions::fromPCL(out_c, output_c);
      pub_p.publish(output_c);
      j++;
    }

  // Convert to ROS data type
  pcl::PCLPointCloud2 out_p;
  pcl::PCLPointCloud2 out_f;
  sensor_msgs::PointCloud2 output_p;
  sensor_msgs::PointCloud2 output_f;
  pcl::toPCLPointCloud2(*cloud_p, out_p);
  pcl::toPCLPointCloud2(*cloud_f, out_f);
  pcl_conversions::fromPCL(out_p, output_p);
  pcl_conversions::fromPCL(out_f, output_f);
  pub_p.publish(output_p);
  pub_f.publish(output_f);
  // output = *input; // only for debuging
  // ROS_INFO_STREAM("cloud_width:" << output.width);
  // pcl_conversions::fromPCL(cloud_filtered, output);

  // Publish the model coefficients
  // pcl_msgs::ModelCoefficients ros_coefficients;
  // pcl_msgs::PointIndices ros_inliers;
  // pcl_conversions::fromPCL(coefficients, ros_coefficients);
  // pcl_conversions::fromPCL(inliers, ros_inliers);
  // pub.publish(ros_coefficients);
  // pub.publish(ros_inliers);
}

int main (int argc, char** argv) {
  // Initialize ROS
  ros::init (argc, argv, "my_pcl_tutorial");
  ros::NodeHandle nh;

  // Create a ROS subscriber for the input point cloud
  // when topic /input is incoming, cloud_cb callback is called
  ros::Subscriber sub = nh.subscribe("assemble_cloud", 1, cloud_cb);

  // Create a ROS publisher for the output point cloud
  // A node has both of publisheres and subscribers.
  pub_p = nh.advertise<sensor_msgs::PointCloud2>("output_p", 1);
  pub_f = nh.advertise<sensor_msgs::PointCloud2>("output_f", 1);
  pub_v = nh.advertise<sensor_msgs::PointCloud2>("output_v", 1);
  pub_c = nh.advertise<sensor_msgs::PointCloud2>("cluster_c", 1);
  // pub = nh.advertise<pcl_msgs::ModelCoefficients>("output", 1);
  // pub = nh.advertise<pcl_msgs::PointIndices>("output", 1);
  // Spin
  ros::spin();
}
<commit_msg>changed topic name used for segmentation.<commit_after>#include <ros/ros.h>
#include <ros/console.h>
#include <sensor_msgs/PointCloud2.h>
// PCL specific includes
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>

ros::Publisher pub_v; // voxel publisher
ros::Publisher pub_p;
ros::Publisher pub_f;
// How to avoid hard-coding a topic name?
ros::Publisher pub_c; // publish cluster

void cloud_cb(const sensor_msgs::PointCloud2ConstPtr& input) {
  // Container for original & filtered data
  pcl::PCLPointCloud2* cloud = new pcl::PCLPointCloud2;
  pcl::PCLPointCloud2ConstPtr cloudPtr(cloud);
  pcl::PCLPointCloud2 cloud_filtered; // (new pcl::PCLPointCloud2);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_templated (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_p (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_f (new pcl::PointCloud<pcl::PointXYZ>);
  pcl_conversions::toPCL(*input, *cloud);

  // StatOutlierRemoval
  // How to use both of SOR and VG?
  /* pcl::StatisticalOutlierRemoval<pcl::PCLPointCloud2> sor_0;
  sor_0.setInputCloud(cloudPtr);
  sor_0.setMeanK(50);
  sor_0.setStddevMulThresh(1.0);
  sor_0.filter(cloud_filtered); // fill in an empty variable */

  // Downsampling
  pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
  sor.setInputCloud(cloudPtr);
  sor.setLeafSize(0.02f, 0.02f, 0.02f);
  sor.filter(cloud_filtered);

  // Publishing voxel
  sensor_msgs::PointCloud2 output_v;
  pcl_conversions::fromPCL(cloud_filtered, output_v);
  pub_v.publish(output_v);

  // Convert
  pcl::fromPCLPointCloud2(cloud_filtered, *cloud_templated); // unused

  /* Perform the actual filtering */
  // Create the segmentation object
  pcl::SACSegmentation<pcl::PointXYZ> seg;
  pcl::PointIndices::Ptr inliers (new pcl::PointIndices ());
  pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
  seg.setOptimizeCoefficients (true); // Optional
  // Mandatory
  seg.setModelType (pcl::SACMODEL_PLANE);
  seg.setMethodType (pcl::SAC_RANSAC);
  seg.setMaxIterations (1000); // added
  seg.setDistanceThreshold (0.02);

  /* Filtering Object: Extraction */
  // pcl::ExtractIndices<pcl::PointXYZ> extract;

  int i = 0, nr_points = (int) cloud_templated->points.size ();
  // While 30% of the original cloud is still there
  while (cloud_templated->points.size () > 0.3 * nr_points)
    {
      // Segment the largest planar component from the remaining cloud
      seg.setInputCloud (cloud_templated);
      seg.segment (*inliers, *coefficients);
      if (inliers->indices.size () == 0)
        {
          ROS_INFO("Could not estimate a planar model for the given dataset.");
          break;
        }

      // Extract the inliers
      pcl::ExtractIndices<pcl::PointXYZ> extract;
      extract.setInputCloud (cloud_templated);
      extract.setIndices (inliers);
      extract.setNegative (false);

      // Get the points associated with the planar surface
      extract.filter (*cloud_p);

      // Remove the planar inliers, extract the rest
      extract.setNegative (true);
      extract.filter (*cloud_f);
      *cloud_templated = *cloud_f;
      // cloud_templated.swap (cloud_f);
      i++;
    }

  // Creating the KdTree object for the search method of the extraction
  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
  tree->setInputCloud (cloud_templated);

  std::vector<pcl::PointIndices> cluster_indices;
  pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
  ec.setClusterTolerance (0.02); // 0.02 = 2ch
  ec.setMinClusterSize (100); // parameter
  ec.setMaxClusterSize (25000); // parameter
  ec.setSearchMethod (tree);
  ec.setInputCloud (cloud_templated);
  ec.extract (cluster_indices);

  int j = 0;
  for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin ();
       it != cluster_indices.end (); ++it) {
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
      for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++)
        cloud_cluster->points.push_back (cloud_templated->points[*pit]); //*
      cloud_cluster->width = cloud_cluster->points.size ();
      cloud_cluster->height = 1;
      cloud_cluster->is_dense = true;

      // Convert data type and publish, but not sure which cluster is published!
      pcl::PCLPointCloud2 out_c;
      sensor_msgs::PointCloud2 output_c;
      pcl::toPCLPointCloud2(*cloud_cluster, out_c);
      pcl_conversions::fromPCL(out_c, output_c);
      pub_p.publish(output_c);
      j++;
    }

  // Convert to ROS data type
  pcl::PCLPointCloud2 out_p;
  pcl::PCLPointCloud2 out_f;
  sensor_msgs::PointCloud2 output_p;
  sensor_msgs::PointCloud2 output_f;
  pcl::toPCLPointCloud2(*cloud_p, out_p);
  pcl::toPCLPointCloud2(*cloud_f, out_f);
  pcl_conversions::fromPCL(out_p, output_p);
  pcl_conversions::fromPCL(out_f, output_f);
  pub_p.publish(output_p);
  pub_f.publish(output_f);
  // output = *input; // only for debuging
  // ROS_INFO_STREAM("cloud_width:" << output.width);
  // pcl_conversions::fromPCL(cloud_filtered, output);

  // Publish the model coefficients
  // pcl_msgs::ModelCoefficients ros_coefficients;
  // pcl_msgs::PointIndices ros_inliers;
  // pcl_conversions::fromPCL(coefficients, ros_coefficients);
  // pcl_conversions::fromPCL(inliers, ros_inliers);
  // pub.publish(ros_coefficients);
  // pub.publish(ros_inliers);
}

int main (int argc, char** argv) {
  // Initialize ROS
  ros::init (argc, argv, "my_pcl_tutorial");
  ros::NodeHandle nh;

  // Create a ROS subscriber for the input point cloud
  // when topic /input is incoming, cloud_cb callback is called
  // /assemble_cloud -> /cloud_pcd
  ros::Subscriber sub = nh.subscribe("cloud_pcd", 1, cloud_cb);

  // Create a ROS publisher for the output point cloud
  // A node has both of publisheres and subscribers.
  pub_p = nh.advertise<sensor_msgs::PointCloud2>("output_p", 1);
  pub_f = nh.advertise<sensor_msgs::PointCloud2>("output_f", 1);
  pub_v = nh.advertise<sensor_msgs::PointCloud2>("output_v", 1);
  pub_c = nh.advertise<sensor_msgs::PointCloud2>("cluster_c", 1);
  // pub = nh.advertise<pcl_msgs::ModelCoefficients>("output", 1);
  // pub = nh.advertise<pcl_msgs::PointIndices>("output", 1);
  // Spin
  ros::spin();
}
<|endoftext|>


<commit_before>#include "board/Board.h"
#include "board/common/indicators/Variables.h"
#include "board/common/uart/Variables.h"
#include "Constants.h"

RingBuff_t   txBuffer[UART_INTERFACES];
RingBuff_t   rxBuffer[UART_INTERFACES];

///
/// \brief Flag determining whether or not UART loopback functionality is enabled.
/// When enabled, all incoming UART traffic is immediately passed on to UART TX.
///
static bool  loopbackEnabled[UART_INTERFACES];

///
/// \brief ISR used to store incoming data from UART to buffer.
/// @{

ISR(USART_RX_vect_0)
{
    uint8_t data = UDR_0;

    if (!loopbackEnabled[0])
    {
        if (!RingBuffer_IsFull(&rxBuffer[0]))
        {
            RingBuffer_Insert(&rxBuffer[0], data);
            UARTreceived = true;
        }
    }
    else
    {
        if (!RingBuffer_IsFull(&txBuffer[0]))
        {
            RingBuffer_Insert(&txBuffer[0], data);
            UCSRB_0 |= (1<<UDRIE_0);
            UARTsent = true;
            UARTreceived = true;
        }
    }
}

#if UART_INTERFACES > 1
ISR(USART_RX_vect_1)
{
    uint8_t data = UDR_1;

    if (!loopbackEnabled[1])
    {
        if (!RingBuffer_IsFull(&rxBuffer[1]))
        {
            RingBuffer_Insert(&rxBuffer[1], data);
            UARTreceived = true;
        }
    }
    else
    {
        if (!RingBuffer_IsFull(&txBuffer[1]))
        {
            RingBuffer_Insert(&txBuffer[1], data);
            UCSRB_1 |= (1<<UDRIE_1);
            UARTsent = true;
            UARTreceived = true;
        }
    }
}
#endif

/// @}

///
/// \brief ISR used to write outgoing data in buffer to UART.
/// @{

ISR(USART_UDRE_vect_0)
{
    if (RingBuffer_IsEmpty(&txBuffer[0]))
    {
        //buffer is empty, disable transmit interrupt
        UCSRB_0 &= ~(1<<UDRIE_0);
    }
    else
    {
        uint8_t data = RingBuffer_Remove(&txBuffer[0]);
        UDR_0 = data;
        UARTsent = true;
    }
}

#if UART_INTERFACES > 1
ISR(USART_UDRE_vect_1)
{
    if (RingBuffer_IsEmpty(&txBuffer[1]))
    {
        //buffer is empty, disable transmit interrupt
        UCSRB_1 &= ~(1<<UDRIE_1);
    }
    else
    {
        uint8_t data = RingBuffer_Remove(&txBuffer[1]);
        UDR_1 = data;
        UARTsent = true;
    }
}
#endif

/// @}

void Board::resetUART(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return;

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
        switch(channel)
        {
            case 0:
            UCSRA_0 = 0;
            UCSRB_0 = 0;
            UCSRC_0 = 0;
            UBRR_0 = 0;
            break;

            #if UART_INTERFACES > 1
            case 1:
            UCSRA_1 = 0;
            UCSRB_1 = 0;
            UCSRC_1 = 0;
            UBRR_1 = 0;
            break;
            #endif

            default:
            break;
        }
    }

    RingBuffer_InitBuffer(&rxBuffer[channel]);
    RingBuffer_InitBuffer(&txBuffer[channel]);
}

void Board::initUART(uint32_t baudRate, uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return;

    resetUART(channel);

    int32_t baud_count = ((F_CPU / 8) + (baudRate / 2)) / baudRate;

    if ((baud_count & 1) && baud_count <= 4096)
    {
        switch(channel)
        {
            case 0:
            UCSRA_0 = (1<<U2X_0); //double speed uart
            UBRR_0 = baud_count - 1;
            break;

            #if UART_INTERFACES > 1
            case 1:
            UCSRA_1 = (1<<U2X_1); //double speed uart
            UBRR_1 = baud_count - 1;
            break;
            #endif

            default:
            break;
        }
    }
    else
    {
        switch(channel)
        {
            case 0:
            UCSRA_0 = 0;
            UBRR_0 = (baud_count >> 1) - 1;
            break;

            #if UART_INTERFACES > 1
            case 1:
            UCSRA_1 = 0;
            UBRR_1 = (baud_count >> 1) - 1;
            break;
            #endif

            default:
            break;
        }
    }

    //8 bit, no parity, 1 stop bit
    //enable receiver, transmitter and receive interrupt
    switch(channel)
    {
        case 0:
        UCSRC_0 = (1<<UCSZ1_0) | (1<<UCSZ0_0);
        UCSRB_0 = (1<<RXEN_0) | (1<<TXEN_0) | (1<<RXCIE_0);
        break;

        #if UART_INTERFACES > 1
        case 1:
        UCSRC_1 = (1<<UCSZ1_1) | (1<<UCSZ0_1);
        UCSRB_1 = (1<<RXEN_1) | (1<<TXEN_1) | (1<<RXCIE_1);
        break;
        #endif

        default:
        break;
    }
}

int16_t Board::uartRead(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return -1;

    if (RingBuffer_IsEmpty(&rxBuffer[channel]))
        return -1;

    uint8_t data = RingBuffer_Remove(&rxBuffer[channel]);

    return data;
}

int8_t Board::uartWrite(uint8_t channel, uint8_t data)
{
    if (channel >= UART_INTERFACES)
        return -1;

    //if both the outgoing buffer and the UART data register are empty
    //write the byte to the data register directly
    if (RingBuffer_IsEmpty(&txBuffer[channel]))
    {
        switch(channel)
        {
            case 0:
            if (UCSRA_0 & (1<<UDRE_0))
            {
                ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
                {
                    UDR_0 = data;
                }
            }
            break;

            #if UART_INTERFACES > 1
            case 1:
            if (UCSRA_1 & (1<<UDRE_1))
            {
                ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
                {
                    UDR_1 = data;
                }
            }
            break;
            #endif

            default:
            return -1;
        }

        return 1;
    }

    while (RingBuffer_IsFull(&txBuffer[channel]));
    RingBuffer_Insert(&txBuffer[channel], data);

    uartTransmitStart(channel);

    return 1;
}

void Board::uartTransmitStart(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return;

    switch(channel)
    {
        case 0:
        UCSRB_0 |= (1<<UDRIE_0);
        break;

        #if UART_INTERFACES > 1
        case 1:
        UCSRB_1 |= (1<<UDRIE_1);
        break;
        #endif

        default:
        break;
    }
}

void Board::setUARTloopbackState(uint8_t channel, bool state)
{
    if (channel >= UART_INTERFACES)
        return;

    loopbackEnabled[channel] = state;
}

bool Board::getUARTloopbackState(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return false;

    return loopbackEnabled[channel];
}<commit_msg>fix handling<commit_after>#include "board/Board.h"
#include "board/common/indicators/Variables.h"
#include "board/common/uart/Variables.h"
#include "Constants.h"

RingBuff_t   txBuffer[UART_INTERFACES];
RingBuff_t   rxBuffer[UART_INTERFACES];

///
/// \brief Flag determining whether or not UART loopback functionality is enabled.
/// When enabled, all incoming UART traffic is immediately passed on to UART TX.
///
static bool  loopbackEnabled[UART_INTERFACES];

///
/// \brief ISR used to store incoming data from UART to buffer.
/// @{

ISR(USART_RX_vect_0)
{
    uint8_t data = UDR_0;

    if (!loopbackEnabled[0])
    {
        if (!RingBuffer_IsFull(&rxBuffer[0]))
        {
            RingBuffer_Insert(&rxBuffer[0], data);
            UARTreceived = true;
        }
    }
    else
    {
        if (!RingBuffer_IsFull(&txBuffer[0]))
        {
            RingBuffer_Insert(&txBuffer[0], data);
            UCSRB_0 |= (1<<UDRIE_0);
            UARTsent = true;
            UARTreceived = true;
        }
    }
}

#if UART_INTERFACES > 1
ISR(USART_RX_vect_1)
{
    uint8_t data = UDR_1;

    if (!loopbackEnabled[1])
    {
        if (!RingBuffer_IsFull(&rxBuffer[1]))
        {
            RingBuffer_Insert(&rxBuffer[1], data);
            UARTreceived = true;
        }
    }
    else
    {
        if (!RingBuffer_IsFull(&txBuffer[1]))
        {
            RingBuffer_Insert(&txBuffer[1], data);
            UCSRB_1 |= (1<<UDRIE_1);
            UARTsent = true;
            UARTreceived = true;
        }
    }
}
#endif

/// @}

///
/// \brief ISR used to write outgoing data in buffer to UART.
/// @{

ISR(USART_UDRE_vect_0)
{
    if (RingBuffer_IsEmpty(&txBuffer[0]))
    {
        //buffer is empty, disable transmit interrupt
        UCSRB_0 &= ~(1<<UDRIE_0);
    }
    else
    {
        uint8_t data = RingBuffer_Remove(&txBuffer[0]);
        UDR_0 = data;
        UARTsent = true;
    }
}

#if UART_INTERFACES > 1
ISR(USART_UDRE_vect_1)
{
    if (RingBuffer_IsEmpty(&txBuffer[1]))
    {
        //buffer is empty, disable transmit interrupt
        UCSRB_1 &= ~(1<<UDRIE_1);
    }
    else
    {
        uint8_t data = RingBuffer_Remove(&txBuffer[1]);
        UDR_1 = data;
        UARTsent = true;
    }
}
#endif

/// @}

void Board::resetUART(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return;

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
        switch(channel)
        {
            case 0:
            UCSRA_0 = 0;
            UCSRB_0 = 0;
            UCSRC_0 = 0;
            UBRR_0 = 0;
            break;

            #if UART_INTERFACES > 1
            case 1:
            UCSRA_1 = 0;
            UCSRB_1 = 0;
            UCSRC_1 = 0;
            UBRR_1 = 0;
            break;
            #endif

            default:
            break;
        }
    }

    RingBuffer_InitBuffer(&rxBuffer[channel]);
    RingBuffer_InitBuffer(&txBuffer[channel]);
}

void Board::initUART(uint32_t baudRate, uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return;

    resetUART(channel);

    int32_t baud_count = ((F_CPU / 8) + (baudRate / 2)) / baudRate;

    if ((baud_count & 1) && baud_count <= 4096)
    {
        switch(channel)
        {
            case 0:
            UCSRA_0 = (1<<U2X_0); //double speed uart
            UBRR_0 = baud_count - 1;
            break;

            #if UART_INTERFACES > 1
            case 1:
            UCSRA_1 = (1<<U2X_1); //double speed uart
            UBRR_1 = baud_count - 1;
            break;
            #endif

            default:
            break;
        }
    }
    else
    {
        switch(channel)
        {
            case 0:
            UCSRA_0 = 0;
            UBRR_0 = (baud_count >> 1) - 1;
            break;

            #if UART_INTERFACES > 1
            case 1:
            UCSRA_1 = 0;
            UBRR_1 = (baud_count >> 1) - 1;
            break;
            #endif

            default:
            break;
        }
    }

    //8 bit, no parity, 1 stop bit
    //enable receiver, transmitter and receive interrupt
    switch(channel)
    {
        case 0:
        UCSRC_0 = (1<<UCSZ1_0) | (1<<UCSZ0_0);
        UCSRB_0 = (1<<RXEN_0) | (1<<TXEN_0) | (1<<RXCIE_0);
        break;

        #if UART_INTERFACES > 1
        case 1:
        UCSRC_1 = (1<<UCSZ1_1) | (1<<UCSZ0_1);
        UCSRB_1 = (1<<RXEN_1) | (1<<TXEN_1) | (1<<RXCIE_1);
        break;
        #endif

        default:
        break;
    }
}

int16_t Board::uartRead(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return -1;

    if (RingBuffer_IsEmpty(&rxBuffer[channel]))
        return -1;

    uint8_t data = RingBuffer_Remove(&rxBuffer[channel]);

    return data;
}

int8_t Board::uartWrite(uint8_t channel, uint8_t data)
{
    if (channel >= UART_INTERFACES)
        return -1;

    //if both the outgoing buffer and the UART data register are empty
    //write the byte to the data register directly
    if (RingBuffer_IsEmpty(&txBuffer[channel]))
    {
        switch(channel)
        {
            case 0:
            if (UCSRA_0 & (1<<UDRE_0))
            {
                ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
                {
                    UDR_0 = data;
                }

                return 1;
            }
            break;

            #if UART_INTERFACES > 1
            case 1:
            if (UCSRA_1 & (1<<UDRE_1))
            {
                ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
                {
                    UDR_1 = data;
                }

                return 1;
            }
            break;
            #endif

            default:
            break;
        }
    }

    while (RingBuffer_IsFull(&txBuffer[channel]));
    RingBuffer_Insert(&txBuffer[channel], data);

    uartTransmitStart(channel);

    return 1;
}

void Board::uartTransmitStart(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return;

    switch(channel)
    {
        case 0:
        UCSRB_0 |= (1<<UDRIE_0);
        break;

        #if UART_INTERFACES > 1
        case 1:
        UCSRB_1 |= (1<<UDRIE_1);
        break;
        #endif

        default:
        break;
    }
}

void Board::setUARTloopbackState(uint8_t channel, bool state)
{
    if (channel >= UART_INTERFACES)
        return;

    loopbackEnabled[channel] = state;
}

bool Board::getUARTloopbackState(uint8_t channel)
{
    if (channel >= UART_INTERFACES)
        return false;

    return loopbackEnabled[channel];
}<|endoftext|>


<commit_before>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

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

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

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

#include "sphere_user.hpp"
#include <fclaw2d_forestclaw.h>

#include <fc2d_clawpack46.h>

static fc2d_clawpack46_vtable_t classic_claw;

static fclaw2d_vtable_t vt;

void sphere_link_solvers(fclaw2d_domain_t *domain)
{
    fclaw2d_init_vtable(&vt);
    fc2d_clawpack46_init_vtable(&classic_claw);

    vt.problem_setup = &fc2d_clawpack46_setprob;
    classic_claw.setprob = &SETPROB;

    vt.patch_setup = &sphere_patch_manifold_setup;
    /* classic_claw.setaux = &SETAUX_SPHERE; */

    vt.patch_initialize = &fc2d_clawpack46_qinit;
    classic_claw.qinit = &QINIT;

    vt.patch_physical_bc = &fc2d_clawpack46_bc2;     /* Needed for lat-long grid */

    vt.patch_single_step_update = &fc2d_clawpack46_update;  /* Includes b4step2 and src2 */
    classic_claw.b4step2 = &B4STEP2;
    classic_claw.rpn2 = &RPN2;
    classic_claw.rpt2 = &RPT2;

    fclaw2d_set_vtable(domain,&vt);
    fc2d_clawpack46_set_vtable(&classic_claw);

}

void sphere_patch_manifold_setup(fclaw2d_domain_t *domain,
                                fclaw2d_patch_t *this_patch,
                                int this_block_idx,
                                int this_patch_idx)
{
    int mx,my,mbc,maux;
    double xlower,ylower,dx,dy;
    double *aux;
    double *xnormals, *ynormals,*xtangents;
    double *ytangents,*surfnormals;
    double *edgelengths, *curvature;

    fc2d_clawpack46_define_auxarray(domain,this_patch);

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);
    fclaw2d_clawpatch_metric_data2(domain,this_patch,&xnormals,&ynormals,
                                   &xtangents,&ytangents,&surfnormals,
                                   &edgelengths,&curvature);

    SETAUX_SPHERE(&mx,&my,&mbc,&xlower,&ylower,
                  &dx,&dy,&maux,aux,xnormals,ynormals,
                  xtangents,ytangents,surfnormals);

    fc2d_clawpack46_set_capacity(domain,this_patch,this_block_idx,this_patch_idx);
}
<commit_msg>(SWE/sphere) Set virtual function for computing area<commit_after>/*
Copyright (c) 2012 Carsten Burstedde, Donna Calhoun
All rights reserved.

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

 * Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

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

#include "sphere_user.hpp"
#include <fclaw2d_forestclaw.h>

#include <fc2d_clawpack46.h>

static fc2d_clawpack46_vtable_t classic_claw;

static fclaw2d_vtable_t vt;

void sphere_link_solvers(fclaw2d_domain_t *domain)
{
    fclaw2d_init_vtable(&vt);
    fc2d_clawpack46_init_vtable(&classic_claw);

    vt.problem_setup = &fc2d_clawpack46_setprob;
    classic_claw.setprob = &SETPROB;

    vt.patch_setup = &sphere_patch_manifold_setup;
    /* classic_claw.setaux = &SETAUX_SPHERE; */

    vt.patch_initialize = &fc2d_clawpack46_qinit;
    classic_claw.qinit = &QINIT;

    vt.patch_physical_bc = &fc2d_clawpack46_bc2;     /* Needed for lat-long grid */

    vt.metric_compute_area = &fclaw2d_metric_compute_area;

    vt.patch_single_step_update = &fc2d_clawpack46_update;  /* Includes b4step2 and src2 */
    classic_claw.b4step2 = &B4STEP2;
    classic_claw.rpn2 = &RPN2;
    classic_claw.rpt2 = &RPT2;

    fclaw2d_set_vtable(domain,&vt);
    fc2d_clawpack46_set_vtable(&classic_claw);

}

void sphere_patch_manifold_setup(fclaw2d_domain_t *domain,
                                fclaw2d_patch_t *this_patch,
                                int this_block_idx,
                                int this_patch_idx)
{
    int mx,my,mbc,maux;
    double xlower,ylower,dx,dy;
    double *aux;
    double *xnormals, *ynormals,*xtangents;
    double *ytangents,*surfnormals;
    double *edgelengths, *curvature;

    fc2d_clawpack46_define_auxarray(domain,this_patch);

    fclaw2d_clawpatch_grid_data(domain,this_patch,&mx,&my,&mbc,
                                &xlower,&ylower,&dx,&dy);

    fc2d_clawpack46_aux_data(domain,this_patch,&aux,&maux);
    fclaw2d_clawpatch_metric_data2(domain,this_patch,&xnormals,&ynormals,
                                   &xtangents,&ytangents,&surfnormals,
                                   &edgelengths,&curvature);

    SETAUX_SPHERE(&mx,&my,&mbc,&xlower,&ylower,
                  &dx,&dy,&maux,aux,xnormals,ynormals,
                  xtangents,ytangents,surfnormals);

    fc2d_clawpack46_set_capacity(domain,this_patch,this_block_idx,this_patch_idx);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: borderconn.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 17:42:48 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SVX_BORDERCONN_HXX
#define SVX_BORDERCONN_HXX

#ifndef SFX_ITEMCONNECT_HXX
#include <sfx2/itemconnect.hxx>
#endif
#ifndef SVX_FRAMEBORDERTYPE_HXX
#include "framebordertype.hxx"
#endif

class SfxItemSet;
class MetricField;
class ValueSet;
class ColorListBox;

namespace svx {

class FrameSelector;

// ============================================================================

/** Creates an item connection object that connects an SvxLineItem with an
    svx::FrameSelector control. */
sfx::ItemConnectionBase* CreateFrameLineConnection( USHORT nSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

/** Creates an item connection object that connects an SvxBoxItem and an
    SvxBoxInfoItem with an svx::FrameSelector control. */
sfx::ItemConnectionBase* CreateFrameBoxConnection(
        USHORT nBoxSlot, USHORT nBoxInfoSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

/** Creates an item connection object that connects an SvxMarginItem with the
    controls of the SvxBorderTabPage. */
sfx::ItemConnectionBase* CreateMarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight,
        MetricField& rMfTop, MetricField& rMfBottom,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

/** Creates an item connection object that connects an SvxShadowItem with the
    controls of the SvxBorderTabPage. */
sfx::ItemConnectionBase* CreateShadowConnection( const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

// ============================================================================

} // namespace svx

#endif

<commit_msg>INTEGRATION: CWS visibility01 (1.2.142); FILE MERGED 2004/11/19 12:54:56 mmeeks 1.2.142.1: Issue number: #i35758# Submitted by: mnicel Reviewed by:  mmeeks<commit_after>/*************************************************************************
 *
 *  $RCSfile: borderconn.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 16:28:02 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc..
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SVX_BORDERCONN_HXX
#define SVX_BORDERCONN_HXX

#ifndef SFX_ITEMCONNECT_HXX
#include <sfx2/itemconnect.hxx>
#endif
#ifndef SVX_FRAMEBORDERTYPE_HXX
#include "framebordertype.hxx"
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

class SfxItemSet;
class MetricField;
class ValueSet;
class ColorListBox;

namespace svx {

class FrameSelector;

// ============================================================================

/** Creates an item connection object that connects an SvxLineItem with an
    svx::FrameSelector control. */
SVX_DLLPUBLIC sfx::ItemConnectionBase* CreateFrameLineConnection( USHORT nSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

/** Creates an item connection object that connects an SvxBoxItem and an
    SvxBoxInfoItem with an svx::FrameSelector control. */
sfx::ItemConnectionBase* CreateFrameBoxConnection(
        USHORT nBoxSlot, USHORT nBoxInfoSlot,
        FrameSelector& rFrameSel, FrameBorderType eBorder,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

/** Creates an item connection object that connects an SvxMarginItem with the
    controls of the SvxBorderTabPage. */
SVX_DLLPUBLIC sfx::ItemConnectionBase* CreateMarginConnection( const SfxItemSet& rItemSet,
        MetricField& rMfLeft, MetricField& rMfRight,
        MetricField& rMfTop, MetricField& rMfBottom,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

/** Creates an item connection object that connects an SvxShadowItem with the
    controls of the SvxBorderTabPage. */
SVX_DLLPUBLIC sfx::ItemConnectionBase* CreateShadowConnection( const SfxItemSet& rItemSet,
        ValueSet& rVsPos, MetricField& rMfSize, ColorListBox& rLbColor,
        sfx::ItemConnFlags nFlags = sfx::ITEMCONN_DEFAULT );

// ============================================================================

} // namespace svx

#endif

<|endoftext|>


<commit_before>//
//  ADSREnvelope.hpp
//  AudioKit Core
//
//  Created by Shane Dunne, revision history on Github.
//  Copyright © 2018 AudioKit. All rights reserved.
//

#include "ADSREnvelope.hpp"
#include <stdio.h>

namespace AudioKitCore
{

    ADSREnvelopeParameters::ADSREnvelopeParameters()
    : sampleRateHz(44100.0f) // a guess, will be overridden later by a call to init(,,,,)
    {
        init(0.0f, 0.0f, 1.0f, 0.0f);
    }

    void ADSREnvelopeParameters::init(float attackSeconds, float decaySeconds, float susFraction, float releaseSeconds)
    {
        attackSamples = attackSeconds * sampleRateHz;
        decaySamples = decaySeconds * sampleRateHz;
        sustainFraction = susFraction;
        releaseSamples = releaseSeconds * sampleRateHz;
    }

    void ADSREnvelopeParameters::init(float newSampleRateHz, float attackSeconds, float decaySeconds, float susFraction, float releaseSeconds)
    {
        sampleRateHz = newSampleRateHz;
        init(attackSeconds, decaySeconds, susFraction, releaseSeconds);
    }

    void ADSREnvelopeParameters::updateSampleRate(float newSampleRateHz)
    {
        float scaleFactor = newSampleRateHz / sampleRateHz;
        sampleRateHz = newSampleRateHz;
        attackSamples *= scaleFactor;
        decaySamples *= scaleFactor;
        releaseSamples *= scaleFactor;
    }

    void ADSREnvelope::init()
    {
        segment = kIdle;
        ramper.init(0.0f);
    }

    void ADSREnvelope::start()
    {
        // have to make attack go above 1.0, or decay won't work if sustain is 1.0
        ramper.init(0.0f, 1.01f, pParameters->attackSamples);
        segment = kAttack;
    }

    void ADSREnvelope::release()
    {
        segment = kRelease;
        if (ramper.value != 0.0f)
            ramper.reinit(0.0f, pParameters->releaseSamples);
    }

    void ADSREnvelope::restart()
    {
        segment = kSilence;
        if (ramper.value != 0.0f)
            ramper.reinit(0.0f, pParameters->releaseSamples);
    }

    void ADSREnvelope::reset()
    {
        ramper.init(0.0f);
        segment = kIdle;
    }

}
<commit_msg>Further fixes for AKSampler release bug<commit_after>//
//  ADSREnvelope.hpp
//  AudioKit Core
//
//  Created by Shane Dunne, revision history on Github.
//  Copyright © 2018 AudioKit. All rights reserved.
//

#include "ADSREnvelope.hpp"
#include <stdio.h>

namespace AudioKitCore
{

    ADSREnvelopeParameters::ADSREnvelopeParameters()
    : sampleRateHz(44100.0f) // a guess, will be overridden later by a call to init(,,,,)
    {
        init(0.0f, 0.0f, 1.0f, 0.0f);
    }

    void ADSREnvelopeParameters::init(float attackSeconds, float decaySeconds, float susFraction, float releaseSeconds)
    {
        attackSamples = attackSeconds * sampleRateHz;
        decaySamples = decaySeconds * sampleRateHz;
        sustainFraction = susFraction;
        releaseSamples = releaseSeconds * sampleRateHz;
    }

    void ADSREnvelopeParameters::init(float newSampleRateHz, float attackSeconds, float decaySeconds, float susFraction, float releaseSeconds)
    {
        sampleRateHz = newSampleRateHz;
        init(attackSeconds, decaySeconds, susFraction, releaseSeconds);
    }

    void ADSREnvelopeParameters::updateSampleRate(float newSampleRateHz)
    {
        float scaleFactor = newSampleRateHz / sampleRateHz;
        sampleRateHz = newSampleRateHz;
        attackSamples *= scaleFactor;
        decaySamples *= scaleFactor;
        releaseSamples *= scaleFactor;
    }

    void ADSREnvelope::init()
    {
        segment = kIdle;
        ramper.init(0.0f);
    }

    void ADSREnvelope::start()
    {
        // have to make attack go above 1.0, or decay won't work if sustain is 1.0
        ramper.init(0.0f, 1.01f, pParameters->attackSamples);
        segment = kAttack;
    }

    void ADSREnvelope::release()
    {
        if (ramper.value == 0.0f) init();
        else
        {
            segment = kRelease;
            ramper.reinit(0.0f, pParameters->releaseSamples);
        }
    }

    void ADSREnvelope::restart()
    {
        if (ramper.value == 0.0f) init();
        else
        {
            segment = kSilence;
            ramper.reinit(0.0f, 0.01f * pParameters->sampleRateHz); // always silence in 10 ms
        }
    }

    void ADSREnvelope::reset()
    {
        init();
    }

}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <gtest/gtest.h>
#include <limits>
#include <uavcan/marshal/types.hpp>
#include <uavcan/transport/transfer_buffer.hpp>

TEST(FloatSpec, Limits)
{
    using uavcan::FloatSpec;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;

    typedef FloatSpec<16, CastModeSaturate> F16S;
    typedef FloatSpec<16, CastModeTruncate> F16T;
    typedef FloatSpec<32, CastModeSaturate> F32S;
    typedef FloatSpec<32, CastModeTruncate> F32T;
    typedef FloatSpec<64, CastModeSaturate> F64S;
    typedef FloatSpec<64, CastModeTruncate> F64T;

    ASSERT_FALSE(F16S::IsExactRepresentation);
    ASSERT_FLOAT_EQ(65504.0, F16S::max());
    ASSERT_FLOAT_EQ(9.77e-04, F16S::epsilon());

    ASSERT_TRUE(F32T::IsExactRepresentation);
    ASSERT_FLOAT_EQ(std::numeric_limits<float>::max(), F32T::max());
    ASSERT_FLOAT_EQ(std::numeric_limits<float>::epsilon(), F32T::epsilon());

    ASSERT_TRUE(F64S::IsExactRepresentation);
    ASSERT_FLOAT_EQ(std::numeric_limits<double>::max(), F64S::max());
    ASSERT_FLOAT_EQ(std::numeric_limits<double>::epsilon(), F64S::epsilon());
}

TEST(FloatSpec, Basic)
{
    using uavcan::FloatSpec;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;
    using uavcan::StorageType;

    typedef FloatSpec<16, CastModeSaturate> F16S;
    typedef FloatSpec<16, CastModeTruncate> F16T;
    typedef FloatSpec<32, CastModeSaturate> F32S;
    typedef FloatSpec<32, CastModeTruncate> F32T;
    typedef FloatSpec<64, CastModeSaturate> F64S;
    typedef FloatSpec<64, CastModeTruncate> F64T;

    static const long double Values[] =
    {
        0.0,
        1.0,
        M_PI,
        123,
        -123,
        99999,
        -999999,
        std::numeric_limits<float>::max(),
        -std::numeric_limits<float>::max(),
        std::numeric_limits<double>::infinity(),
        -std::numeric_limits<double>::infinity(),
        nanl("")
    };
    static const int NumValues = sizeof(Values) / sizeof(Values[0]);

    static const long double ValuesF16S[] =
    {
        0.0,
        1.0,
        3.140625,
        123,
        -123,
        F16S::max(),
        -F16S::max(),
        F16S::max(),
        -F16S::max(),
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        nanl("")
    };
    static const long double ValuesF16T[] =
    {
        0.0,
        1.0,
        3.140625,
        123,
        -123,
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        nanl("")
    };

    /*
     * Writing
     */
    uavcan::StaticTransferBuffer<NumValues * (2 + 4 + 8) * 2> buf;
    uavcan::BitStream bs_wr(buf);
    uavcan::ScalarCodec sc_wr(bs_wr);

    for (int i = 0; i < NumValues; i++)
    {
        ASSERT_EQ(1, F16S::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F16T::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F32S::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F32T::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F64S::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F64T::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
    }

    ASSERT_EQ(0, F16S::encode(0, sc_wr, uavcan::TailArrayOptDisabled));  // Out of buffer space now

    /*
     * Reading
     */
    uavcan::BitStream bs_rd(buf);
    uavcan::ScalarCodec sc_rd(bs_rd);

#define CHECK(FloatType, expected_value) \
    do { \
        StorageType<FloatType>::Type var = StorageType<FloatType>::Type(); \
        ASSERT_EQ(1, FloatType::decode(var, sc_rd, uavcan::TailArrayOptDisabled)); \
        if (!isnan(expected_value)) { \
            ASSERT_FLOAT_EQ(expected_value, var); } \
        else { \
            ASSERT_EQ(!!isnan(expected_value), !!isnan(var)); } \
    } while (0)

    for (int i = 0; i < NumValues; i++)
    {
        CHECK(F16S, ValuesF16S[i]);
        CHECK(F16T, ValuesF16T[i]);
        CHECK(F32S, Values[i]);
        CHECK(F32T, Values[i]);
        CHECK(F64S, Values[i]);
        CHECK(F64T, Values[i]);
    }

#undef CHECK
}

TEST(FloatSpec, Float16Representation)
{
    using uavcan::FloatSpec;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;

    typedef FloatSpec<16, CastModeSaturate> F16S;
    typedef FloatSpec<16, CastModeTruncate> F16T;

    uavcan::StaticTransferBuffer<2 * 6> buf;
    uavcan::BitStream bs_wr(buf);
    uavcan::ScalarCodec sc_wr(bs_wr);

    ASSERT_EQ(1, F16S::encode(0.0, sc_wr, uavcan::TailArrayOptDisabled));
    ASSERT_EQ(1, F16S::encode(1.0, sc_wr, uavcan::TailArrayOptDisabled));
    ASSERT_EQ(1, F16S::encode(-2.0, sc_wr, uavcan::TailArrayOptDisabled));
    ASSERT_EQ(1, F16T::encode(999999, sc_wr, uavcan::TailArrayOptDisabled));  // +inf
    ASSERT_EQ(1, F16S::encode(-999999, sc_wr, uavcan::TailArrayOptDisabled)); // -max
    ASSERT_EQ(1, F16S::encode(nan(""), sc_wr, uavcan::TailArrayOptDisabled)); // nan

    ASSERT_EQ(0, F16S::encode(0, sc_wr, uavcan::TailArrayOptDisabled));  // Out of buffer space now

    // Keep in mind that this is LITTLE ENDIAN representation
    static const std::string Reference =
        "00000000 00000000 " // 0.0
        "00000000 00111100 " // 1.0
        "00000000 11000000 " // -2.0
        "00000000 01111100 " // +inf
        "11111111 11111011 " // -max
        "11111111 01111111"; // nan

    ASSERT_EQ(Reference, bs_wr.toString());
}
<commit_msg>libuavcan test: removed unused local type declarations<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <gtest/gtest.h>
#include <limits>
#include <uavcan/marshal/types.hpp>
#include <uavcan/transport/transfer_buffer.hpp>

TEST(FloatSpec, Limits)
{
    using uavcan::FloatSpec;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;

    typedef FloatSpec<16, CastModeSaturate> F16S;
    typedef FloatSpec<32, CastModeTruncate> F32T;
    typedef FloatSpec<64, CastModeSaturate> F64S;

    ASSERT_FALSE(F16S::IsExactRepresentation);
    ASSERT_FLOAT_EQ(65504.0, F16S::max());
    ASSERT_FLOAT_EQ(9.77e-04, F16S::epsilon());

    ASSERT_TRUE(F32T::IsExactRepresentation);
    ASSERT_FLOAT_EQ(std::numeric_limits<float>::max(), F32T::max());
    ASSERT_FLOAT_EQ(std::numeric_limits<float>::epsilon(), F32T::epsilon());

    ASSERT_TRUE(F64S::IsExactRepresentation);
    ASSERT_FLOAT_EQ(std::numeric_limits<double>::max(), F64S::max());
    ASSERT_FLOAT_EQ(std::numeric_limits<double>::epsilon(), F64S::epsilon());
}

TEST(FloatSpec, Basic)
{
    using uavcan::FloatSpec;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;
    using uavcan::StorageType;

    typedef FloatSpec<16, CastModeSaturate> F16S;
    typedef FloatSpec<16, CastModeTruncate> F16T;
    typedef FloatSpec<32, CastModeSaturate> F32S;
    typedef FloatSpec<32, CastModeTruncate> F32T;
    typedef FloatSpec<64, CastModeSaturate> F64S;
    typedef FloatSpec<64, CastModeTruncate> F64T;

    static const long double Values[] =
    {
        0.0,
        1.0,
        M_PI,
        123,
        -123,
        99999,
        -999999,
        std::numeric_limits<float>::max(),
        -std::numeric_limits<float>::max(),
        std::numeric_limits<double>::infinity(),
        -std::numeric_limits<double>::infinity(),
        nanl("")
    };
    static const int NumValues = sizeof(Values) / sizeof(Values[0]);

    static const long double ValuesF16S[] =
    {
        0.0,
        1.0,
        3.140625,
        123,
        -123,
        F16S::max(),
        -F16S::max(),
        F16S::max(),
        -F16S::max(),
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        nanl("")
    };
    static const long double ValuesF16T[] =
    {
        0.0,
        1.0,
        3.140625,
        123,
        -123,
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        std::numeric_limits<F16S::StorageType>::infinity(),
        -std::numeric_limits<F16S::StorageType>::infinity(),
        nanl("")
    };

    /*
     * Writing
     */
    uavcan::StaticTransferBuffer<NumValues * (2 + 4 + 8) * 2> buf;
    uavcan::BitStream bs_wr(buf);
    uavcan::ScalarCodec sc_wr(bs_wr);

    for (int i = 0; i < NumValues; i++)
    {
        ASSERT_EQ(1, F16S::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F16T::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F32S::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F32T::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F64S::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
        ASSERT_EQ(1, F64T::encode(Values[i], sc_wr, uavcan::TailArrayOptDisabled));
    }

    ASSERT_EQ(0, F16S::encode(0, sc_wr, uavcan::TailArrayOptDisabled));  // Out of buffer space now

    /*
     * Reading
     */
    uavcan::BitStream bs_rd(buf);
    uavcan::ScalarCodec sc_rd(bs_rd);

#define CHECK(FloatType, expected_value) \
    do { \
        StorageType<FloatType>::Type var = StorageType<FloatType>::Type(); \
        ASSERT_EQ(1, FloatType::decode(var, sc_rd, uavcan::TailArrayOptDisabled)); \
        if (!isnan(expected_value)) { \
            ASSERT_FLOAT_EQ(expected_value, var); } \
        else { \
            ASSERT_EQ(!!isnan(expected_value), !!isnan(var)); } \
    } while (0)

    for (int i = 0; i < NumValues; i++)
    {
        CHECK(F16S, ValuesF16S[i]);
        CHECK(F16T, ValuesF16T[i]);
        CHECK(F32S, Values[i]);
        CHECK(F32T, Values[i]);
        CHECK(F64S, Values[i]);
        CHECK(F64T, Values[i]);
    }

#undef CHECK
}

TEST(FloatSpec, Float16Representation)
{
    using uavcan::FloatSpec;
    using uavcan::CastModeSaturate;
    using uavcan::CastModeTruncate;

    typedef FloatSpec<16, CastModeSaturate> F16S;
    typedef FloatSpec<16, CastModeTruncate> F16T;

    uavcan::StaticTransferBuffer<2 * 6> buf;
    uavcan::BitStream bs_wr(buf);
    uavcan::ScalarCodec sc_wr(bs_wr);

    ASSERT_EQ(1, F16S::encode(0.0, sc_wr, uavcan::TailArrayOptDisabled));
    ASSERT_EQ(1, F16S::encode(1.0, sc_wr, uavcan::TailArrayOptDisabled));
    ASSERT_EQ(1, F16S::encode(-2.0, sc_wr, uavcan::TailArrayOptDisabled));
    ASSERT_EQ(1, F16T::encode(999999, sc_wr, uavcan::TailArrayOptDisabled));  // +inf
    ASSERT_EQ(1, F16S::encode(-999999, sc_wr, uavcan::TailArrayOptDisabled)); // -max
    ASSERT_EQ(1, F16S::encode(nan(""), sc_wr, uavcan::TailArrayOptDisabled)); // nan

    ASSERT_EQ(0, F16S::encode(0, sc_wr, uavcan::TailArrayOptDisabled));  // Out of buffer space now

    // Keep in mind that this is LITTLE ENDIAN representation
    static const std::string Reference =
        "00000000 00000000 " // 0.0
        "00000000 00111100 " // 1.0
        "00000000 11000000 " // -2.0
        "00000000 01111100 " // +inf
        "11111111 11111011 " // -max
        "11111111 01111111"; // nan

    ASSERT_EQ(Reference, bs_wr.toString());
}
<|endoftext|>


<commit_before>#include "ContainerWithMostWater.hpp"

#include <algorithm>
using namespace std;

int Solution::maxArea(vector<int>& height)
{
  if (height.size() < 2) return 0;

  int i = 0;
  int j = height.size() - 1;
  int area = min(height[i], height[j]) * (j - i);

  while (i < j) {
    if (height[i] < height[j]) {
      int k = i + 1;
      while (k < j) {
        if (height[k] > height[i] && min(height[k], height[j]) * (j - k) > area)
          area = min(height[k], height[j]) * (j - k);
        if (height[k] > height[j]) break;
        k++;
      }
      if (k == j) break;
      else i = k;
    } else {
      int k = j - 1;
      while (k > i) {
        if (height[k] > height[j] && min(height[k], height[i]) * (k - i) > area)
          area = min(height[k], height[i]) * (k - i);
        if (height[k] > height[i]) break;
        k--;
      }
      if (k == i) break;
      else j = k;
    }
  }
  return area;
}
<commit_msg>Update Problem 11 solution<commit_after>#include "ContainerWithMostWater.hpp"

#include <algorithm>
using namespace std;

int Solution::maxArea(vector<int>& height)
{
  if (height.size() < 2) return 0;

  int i = 0;
  int j = height.size() - 1;
  int area = min(height[i], height[j]) * (j - i);

  while (i < j) {
    area = max(area, min(height[i], height[j]) * (j - i));
    if (height[i] < height[j]) i++;
    else j--;
  }
  return area;
}
<|endoftext|>