<commit_before>#include <algorithm>
#include <random>
#include <vector>

#include <transformer.hh>

allrgb::Transformer::Transformer(cv::Mat& input)
  : img_(input)
  , colors_(9)
{}

cv::Mat&
allrgb::Transformer::img_get() const
{
  return img_;
}

void
allrgb::Transformer::operator()()
{
  std::vector<cv::Point> points;
  points.reserve(4096 * 4096);
  for (size_t y = 0; y < 4096; ++y)
    for (size_t x = 0; x < 4096; ++x)
      points.emplace_back(x, y);
  std::random_device rd;
  // TODO more effective
  std::shuffle(points.begin(), points.end(), rd);

  while (points.size() > 0)
  {
    cv::Point& point = *points.end();
    replace_color_(img_.at<cv::Vec3b>(point));
    points.pop_back();
  }
}

void
allrgb::Transformer::replace_color_(cv::Vec3b& color)
{
  const uchar blue = color[0];
  const uchar green = color[1];
  const uchar red = color[2];

  uchar new_red = 0;
  uchar new_green = 0;
  uchar new_blue = 0;

  size_t octree_index = 0;

  for (unsigned i = 0; i < 8; ++i)
  {
    const size_t perfect_child = ocnode_index_(red, green, blue, i);
    const size_t prev_octree_index = octree_index;
    octree_index = colors_.index_child(prev_octree_index, perfect_child);

    size_t last_chosen = perfect_child;
    size_t nb_try = 0;
    while (colors_.at(octree_index) <= 0)
    {
      last_chosen = next_lookup_(perfect_child, ++nb_try);
      octree_index = colors_.index_child(prev_octree_index, last_chosen);
    }
    choose_child_(new_red, new_green, new_blue, last_chosen);
  }

  colors_.delete_leaf(octree_index);

  color[0] = new_blue;
  color[1] = new_green;
  color[2] = new_red;
}

// bit_index = 0 is the LSB
uchar
allrgb::Transformer::bdigit_(const uchar value, const size_t bit_index)
{
  assert(bit_index < 8);

  const uchar mask = 0b00000001 << bit_index;
  return (value & mask) >> bit_index;
}

size_t
allrgb::Transformer::ocnode_index_(const uchar r, const uchar g, const uchar b,
                                   const size_t ocnode_depth)
{
  assert(ocnode_depth < 8);

  const size_t bindex = 7 - ocnode_depth;

  size_t res = 0;
  res = bdigit_(r, bindex);
  res = (res << 1) | bdigit_(g, bindex);
  res = (res << 1) | bdigit_(b, bindex);
  return res;
}

void
allrgb::Transformer::choose_child_(uchar& r, uchar& g, uchar& b,
                                   const size_t nb_child)
{
  assert(nb_child < 8);

  const uchar red_digit = (nb_child & 0b00000100) >> 2;
  const uchar green_digit = (nb_child & 0b00000010) >> 1;
  const uchar blue_digit = nb_child & 0b00000001;

  r = (r << 1) | red_digit;
  g = (g << 1) | green_digit;
  b = (b << 1) | blue_digit;
}

size_t
allrgb::Transformer::next_lookup_(const size_t perfect, const size_t nb_try)
{
  assert(perfect < 8 && nb_try < 8);

  const static size_t lookup_table[8][8] = {
    {0, 1, 4, 5, 2, 3, 6, 7},
    {1, 0, 5, 4, 3, 2, 7, 6},
    {2, 3, 6, 7, 0, 1, 4, 5},
    {3, 2, 7, 6, 1, 0, 5, 4},
    {4, 5, 0, 1, 6, 7, 2, 3},
    {5, 4, 1, 0, 7, 6, 3, 2},
    {6, 7, 2, 3, 4, 5, 0, 1},
    {7, 6, 3, 2, 5, 4, 1, 0}
  };

  return lookup_table[perfect][nb_try];
}
<commit_msg>[TRANSFORM] Add preconditions and postconditions to operator()<commit_after>#include <algorithm>
#include <random>
#include <vector>

#include <transformer.hh>

allrgb::Transformer::Transformer(cv::Mat& input)
  : img_(input)
  , colors_(9)
{}

cv::Mat&
allrgb::Transformer::img_get() const
{
  return img_;
}

void
allrgb::Transformer::operator()()
{
  assert(colors_.at(0) == 4096 * 4096);

  std::vector<cv::Point> points;
  points.reserve(4096 * 4096);
  for (size_t y = 0; y < 4096; ++y)
    for (size_t x = 0; x < 4096; ++x)
      points.emplace_back(x, y);
  std::random_device rd;
  // TODO more effective
  std::shuffle(points.begin(), points.end(), rd);

  while (points.size() > 0)
  {
    cv::Point& point = *points.end();
    replace_color_(img_.at<cv::Vec3b>(point));
    points.pop_back();
  }

  assert(colors_.at(0) == 0);
}

void
allrgb::Transformer::replace_color_(cv::Vec3b& color)
{
  const uchar blue = color[0];
  const uchar green = color[1];
  const uchar red = color[2];

  uchar new_red = 0;
  uchar new_green = 0;
  uchar new_blue = 0;

  size_t octree_index = 0;

  for (unsigned i = 0; i < 8; ++i)
  {
    const size_t perfect_child = ocnode_index_(red, green, blue, i);
    const size_t prev_octree_index = octree_index;
    octree_index = colors_.index_child(prev_octree_index, perfect_child);

    size_t last_chosen = perfect_child;
    size_t nb_try = 0;
    while (colors_.at(octree_index) <= 0)
    {
      last_chosen = next_lookup_(perfect_child, ++nb_try);
      octree_index = colors_.index_child(prev_octree_index, last_chosen);
    }
    choose_child_(new_red, new_green, new_blue, last_chosen);
  }

  colors_.delete_leaf(octree_index);

  color[0] = new_blue;
  color[1] = new_green;
  color[2] = new_red;
}

// bit_index = 0 is the LSB
uchar
allrgb::Transformer::bdigit_(const uchar value, const size_t bit_index)
{
  assert(bit_index < 8);

  const uchar mask = 0b00000001 << bit_index;
  return (value & mask) >> bit_index;
}

size_t
allrgb::Transformer::ocnode_index_(const uchar r, const uchar g, const uchar b,
                                   const size_t ocnode_depth)
{
  assert(ocnode_depth < 8);

  const size_t bindex = 7 - ocnode_depth;

  size_t res = 0;
  res = bdigit_(r, bindex);
  res = (res << 1) | bdigit_(g, bindex);
  res = (res << 1) | bdigit_(b, bindex);
  return res;
}

void
allrgb::Transformer::choose_child_(uchar& r, uchar& g, uchar& b,
                                   const size_t nb_child)
{
  assert(nb_child < 8);

  const uchar red_digit = (nb_child & 0b00000100) >> 2;
  const uchar green_digit = (nb_child & 0b00000010) >> 1;
  const uchar blue_digit = nb_child & 0b00000001;

  r = (r << 1) | red_digit;
  g = (g << 1) | green_digit;
  b = (b << 1) | blue_digit;
}

size_t
allrgb::Transformer::next_lookup_(const size_t perfect, const size_t nb_try)
{
  assert(perfect < 8 && nb_try < 8);

  const static size_t lookup_table[8][8] = {
    {0, 1, 4, 5, 2, 3, 6, 7},
    {1, 0, 5, 4, 3, 2, 7, 6},
    {2, 3, 6, 7, 0, 1, 4, 5},
    {3, 2, 7, 6, 1, 0, 5, 4},
    {4, 5, 0, 1, 6, 7, 2, 3},
    {5, 4, 1, 0, 7, 6, 3, 2},
    {6, 7, 2, 3, 4, 5, 0, 1},
    {7, 6, 3, 2, 5, 4, 1, 0}
  };

  return lookup_table[perfect][nb_try];
}
<|endoftext|>


<commit_before>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * type_utils.hpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#pragma once

#include "constants.hpp"

#include <type_traits>
#include <tuple>

namespace bbb {
	template <typename T>
	using get_type = typename T::type;

	template <bool b, typename T = void>
	using enable_if = get_type<std::enable_if<b, T>>;

	template <typename T>
	constexpr bool is_const() {
		return std::is_const<T>::value;
	}

	template <typename T>
	constexpr bool is_number() {
		return std::is_arithmetic<T>::value;
	}

	template <typename T>
	constexpr bool is_integer() {
		return std::is_integral<T>::value;
	}

	template <typename T>
	constexpr bool is_float() {
		return std::is_floating_point<T>::value;
	}

	template <typename T>
	using remove_const_reference_if_number = get_type<std::conditional<
		is_number<T>(),
		get_type<std::remove_reference<
			get_type<std::remove_const<T>>
		>>,
		T
	>>;

	template <typename T>
	using add_const_reference_if_not_number = get_type<std::conditional<
		!is_number<T>(),
		get_type<std::add_const<
			get_type<std::add_lvalue_reference<T>>
		>>,
		T
	>>;

	namespace function_traits {
		template <typename T>
		struct function_info : public function_info<decltype(&T::operator())> {};

		template <typename class_type, typename ret, typename ... arguments>
		struct function_info<ret(class_type::*)(arguments ...) const> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template <typename class_type, typename ret, typename ... arguments>
		struct function_info<ret(class_type::*)(arguments ...)> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template <typename ret, typename ... arguments>
		struct function_info<ret(*)(arguments ...)> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template<typename T>
		using result_type = typename function_info<T>::result_type;
		template<typename T>
		using arguments_types_tuple = typename function_info<T>::arguments_types_tuple;
		template<typename T, std::size_t index>
		using argument_type = typename function_info<T>::template argument_type<index>;
		template<typename T>
		struct arity {
			static constexpr std::size_t value = function_info<T>::arity;
		};
	};
	using namespace function_traits;
};<commit_msg>treat<commit_after>/* **** **** **** **** **** **** **** **** *
 *
 *         _/        _/        _/
 *        _/_/_/    _/_/_/    _/_/_/
 *       _/    _/  _/    _/  _/    _/
 *      _/    _/  _/    _/  _/    _/
 *     _/_/_/    _/_/_/    _/_/_/
 *
 * bit by bit
 * type_utils.hpp
 *
 * author: ISHII 2bit
 * mail:   2bit@backspace.tokyo
 *
 * **** **** **** **** **** **** **** **** */

#pragma once

#include "constants.hpp"

#include <type_traits>
#include <tuple>

namespace bbb {
	template <typename T>
	using get_type = typename T::type;

	template <bool b, typename T = void>
	using enable_if = get_type<std::enable_if<b, T>>;

	template <typename T>
	constexpr bool is_const() {
		return std::is_const<T>::value;
	}

	template <typename T>
	constexpr bool is_number() {
		return std::is_arithmetic<T>::value;
	}

	template <typename T>
	constexpr bool is_integer() {
		return std::is_integral<T>::value;
	}

	template <typename T>
	constexpr bool is_float() {
		return std::is_floating_point<T>::value;
	}

	template <typename T>
	using remove_const_reference_if_number = get_type<std::conditional<
		is_number<T>(),
		get_type<std::remove_reference<
			get_type<std::remove_const<T>>
		>>,
		T
	>>;

	template <typename T>
	using add_const_reference_if_not_number = get_type<std::conditional<
		!is_number<T>(),
		get_type<std::add_const<
			get_type<std::add_lvalue_reference<T>>
		>>,
		T
	>>;

	namespace function_traits {
		template <typename T>
		struct function_info : public function_info<decltype(&T::operator())> {};

		template <typename class_type, typename ret, typename ... arguments>
		struct function_info<ret(class_type::*)(arguments ...) const> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template <typename class_type, typename ret, typename ... arguments>
		struct function_info<ret(class_type::*)(arguments ...)> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template <typename ret, typename ... arguments>
		struct function_info<ret(*)(arguments ...)> {
			static constexpr std::size_t arity = sizeof...(arguments);
			using result_type = ret;
			using arguments_types_tuple = std::tuple<arguments ...>;
			template <std::size_t index>
			using argument_type = get_type<std::tuple_element<index, arguments_types_tuple>>;
		};

		template<typename T>
		using result_type = typename function_info<T>::result_type;

		template<typename T>
		using arguments_types_tuple = typename function_info<T>::arguments_types_tuple;

		template<typename T, std::size_t index>
		using argument_type = typename function_info<T>::template argument_type<index>;

		template<typename T>
		struct arity {
			static constexpr std::size_t value = function_info<T>::arity;
		};
	};
	using namespace function_traits;
};<|endoftext|>


<commit_before>#include "helloworld_DCPS.hpp"

int main(int argc, char *arv[])
{
    /* Create DomainParticipant - this connects the application to DDS */
    dds::domain::DomainParticipant dp( org::opensplice::domain::default_id() );

    /* Create a topic - this is like a db table or queue (depending on QoS). */
    dds::topic::Topic<Hello::World> topic( dp, "HelloWorld" );

    /* Create a datawriter - lets the application publish to a topic */
    dds::pub::DataWriter<Hello::World> dw( dp, topic, topic.qos() );

    /* Create and write a sample */
    Hello::World sample;
    sample.id( 0 );
    sample.value( "Hello World" );
    dw << sample;

    return 0;
}
<commit_msg>Changed write into one-liner<commit_after>#include "helloworld_DCPS.hpp"

int main(int argc, char *arv[])
{
    /* Create DomainParticipant - this connects the application to DDS */
    dds::domain::DomainParticipant dp( org::opensplice::domain::default_id() );

    /* Create a topic - this is like a db table or queue (depending on QoS). */
    dds::topic::Topic<Hello::World> topic( dp, "HelloWorld" );

    /* Create a datawriter - lets the application publish to a topic */
    dds::pub::DataWriter<Hello::World> dw( dp, topic, topic.qos() );

    /* Create and write a sample */
    dw << Hello::World(0, "Hello World");

    return 0;
}
<|endoftext|>


<commit_before>// This file is part of the Yttrium toolkit.
// Copyright (C) Sergei Blagodarin.
// SPDX-License-Identifier: Apache-2.0

#include <yttrium/gui/gui.h>

#include <yttrium/application/key.h>
#include <yttrium/application/window.h>
#include <yttrium/math/point.h>
#include <yttrium/math/rect.h>

#include <algorithm>
#include <cassert>
#include <string>
#include <vector>

namespace Yt
{
	class GuiStateData
	{
	public:
		static constexpr uint16_t kPayloadMask = 0x00ff;
		static constexpr uint16_t kPressedFlag = 0x0100;
		static constexpr uint16_t kAutorepeatFlag = 0x0200;
		static constexpr uint16_t kTextFlag = 0x4000;
		static constexpr uint16_t kProcessedFlag = 0x8000;
		static constexpr uint16_t kKeySearchMask = kPayloadMask | kTextFlag | kProcessedFlag;

		Window& _window;
		std::optional<Vector2> _cursor;
		std::vector<uint16_t> _inputEvents;
		std::string _cursorItem;
		Key _cursorItemKey = Key::Null;

		explicit GuiStateData(Window& window) noexcept
			: _window{ window } {}

		std::pair<unsigned, bool> captureClick(Key key, bool autorepeat) noexcept
		{
			const auto i = std::find_if(_inputEvents.begin(), _inputEvents.end(), [key](const auto event) {
				return (event & kKeySearchMask) == static_cast<uint8_t>(key);
			});
			if (i == _inputEvents.end())
				return { 0u, false };
			*i |= kProcessedFlag;
			if (!(*i & kPressedFlag))
				return { 0u, true };
			auto count = static_cast<unsigned>(!(*i & kAutorepeatFlag) || autorepeat);
			for (auto j = std::next(i); j != _inputEvents.end(); ++j)
			{
				if ((*j & kKeySearchMask) != static_cast<uint8_t>(key))
					continue;
				*j |= kProcessedFlag;
				if (!(*j & kPressedFlag))
					return { count, true };
				assert(*j & kAutorepeatFlag); // Either it is autorepeat, or we've missed some events.
				if (autorepeat)
					++count;
			}
			return { count, false };
		}
	};

	GuiState::GuiState(Window& window)
		: _data{ std::make_unique<GuiStateData>(window) }
	{
	}

	GuiState::~GuiState() noexcept = default;

	void GuiState::processKeyEvent(const KeyEvent& event)
	{
		auto encodedEvent = static_cast<uint16_t>(event._key);
		if (event._pressed)
		{
			encodedEvent |= GuiStateData::kPressedFlag;
			if (event._autorepeat)
				encodedEvent |= GuiStateData::kAutorepeatFlag;
		}
		else if (!_data->_cursorItem.empty() && _data->_cursorItemKey == event._key)
		{
			_data->_cursorItem.clear();
			_data->_cursorItemKey = Key::Null;
		}
		_data->_inputEvents.emplace_back(encodedEvent);
	}

	GuiFrame::GuiFrame(GuiState& state)
		: _state{ *state._data }
	{
		_state._cursor.emplace(_state._window.cursor());
	}

	GuiFrame::~GuiFrame() noexcept
	{
		_state._inputEvents.clear();
	}

	bool GuiFrame::captureKeyDown(Key key) noexcept
	{
		return _state.captureClick(key, false).first > 0;
	}

	std::optional<Vector2> GuiFrame::dragArea(std::string_view id, const RectF& rect, Key key)
	{
		assert(!id.empty());
		if (_state._cursorItem == id)
		{
			assert(_state._cursor);
			auto captured = rect.bound(*_state._cursor);
			_state._cursor.reset();
			return captured;
		}
		if (_state._cursorItem.empty())
			if (auto maybeCaptured = hoverArea(rect))
				if (const auto [down, up] = _state.captureClick(key, false); down > 0)
				{
					if (!up)
					{
						_state._cursorItem = id; // May throw std::bad_alloc.
						_state._cursorItemKey = key;
					}
					return maybeCaptured;
				}
		return {};
	}

	std::optional<Vector2> GuiFrame::hoverArea(const RectF& rect) noexcept
	{
		std::optional<Vector2> captured;
		if (_state._cursor && rect.contains(*_state._cursor))
			captured.swap(_state._cursor);
		return captured;
	}
}
<commit_msg>Fix double key press handling<commit_after>// This file is part of the Yttrium toolkit.
// Copyright (C) Sergei Blagodarin.
// SPDX-License-Identifier: Apache-2.0

#include <yttrium/gui/gui.h>

#include <yttrium/application/key.h>
#include <yttrium/application/window.h>
#include <yttrium/math/rect.h>

#include <algorithm>
#include <cassert>
#include <string>
#include <vector>

namespace Yt
{
	class GuiStateData
	{
	public:
		static constexpr uint16_t kPayloadMask = 0x00ff;
		static constexpr uint16_t kPressedFlag = 0x0100;
		static constexpr uint16_t kAutorepeatFlag = 0x0200;
		static constexpr uint16_t kTextFlag = 0x4000;
		static constexpr uint16_t kProcessedFlag = 0x8000;
		static constexpr uint16_t kKeySearchMask = kPayloadMask | kTextFlag | kProcessedFlag;

		Window& _window;
		std::optional<Vector2> _cursor;
		std::vector<uint16_t> _inputEvents;
		std::string _cursorItem;
		Key _cursorItemKey = Key::Null;

		explicit GuiStateData(Window& window) noexcept
			: _window{ window } {}

		std::pair<unsigned, bool> captureClick(Key key, bool autorepeat) noexcept
		{
			const auto i = std::find_if(_inputEvents.begin(), _inputEvents.end(), [key](const auto event) {
				return (event & kKeySearchMask) == static_cast<uint8_t>(key);
			});
			if (i == _inputEvents.end())
				return { 0u, false };
			*i |= kProcessedFlag;
			if (!(*i & kPressedFlag))
				return { 0u, true };
			auto count = static_cast<unsigned>(!(*i & kAutorepeatFlag) || autorepeat);
			for (auto j = std::next(i); j != _inputEvents.end(); ++j)
			{
				if ((*j & kKeySearchMask) == static_cast<uint8_t>(key))
				{
					if (!(*j & kAutorepeatFlag))
					{
						if (!(*j & kPressedFlag))
							*j |= kProcessedFlag;
						return { count, true };
					}
					assert(*j & kPressedFlag);
					*j |= kProcessedFlag;
					if (autorepeat)
						++count;
				}
			}
			return { count, false };
		}
	};

	GuiState::GuiState(Window& window)
		: _data{ std::make_unique<GuiStateData>(window) }
	{
	}

	GuiState::~GuiState() noexcept = default;

	void GuiState::processKeyEvent(const KeyEvent& event)
	{
		auto encodedEvent = static_cast<uint16_t>(event._key);
		if (event._pressed)
		{
			encodedEvent |= GuiStateData::kPressedFlag;
			if (event._autorepeat)
				encodedEvent |= GuiStateData::kAutorepeatFlag;
		}
		else if (!_data->_cursorItem.empty() && _data->_cursorItemKey == event._key)
		{
			_data->_cursorItem.clear();
			_data->_cursorItemKey = Key::Null;
		}
		_data->_inputEvents.emplace_back(encodedEvent);
	}

	GuiFrame::GuiFrame(GuiState& state)
		: _state{ *state._data }
	{
		_state._cursor.emplace(_state._window.cursor());
	}

	GuiFrame::~GuiFrame() noexcept
	{
		_state._inputEvents.clear();
	}

	bool GuiFrame::captureKeyDown(Key key) noexcept
	{
		return _state.captureClick(key, false).first > 0;
	}

	std::optional<Vector2> GuiFrame::dragArea(std::string_view id, const RectF& rect, Key key)
	{
		assert(!id.empty());
		if (_state._cursorItem == id)
		{
			assert(_state._cursor);
			auto captured = rect.bound(*_state._cursor);
			_state._cursor.reset();
			return captured;
		}
		if (_state._cursorItem.empty())
			if (auto maybeCaptured = hoverArea(rect))
				if (const auto [pressed, released] = _state.captureClick(key, false); pressed)
				{
					if (!released)
					{
						_state._cursorItem = id; // May throw std::bad_alloc.
						_state._cursorItemKey = key;
					}
					return maybeCaptured;
				}
		return {};
	}

	std::optional<Vector2> GuiFrame::hoverArea(const RectF& rect) noexcept
	{
		std::optional<Vector2> captured;
		if (_state._cursor && rect.contains(*_state._cursor))
			captured.swap(_state._cursor);
		return captured;
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM 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) version 2.1 dated February 1999.

#include "multigrid.hpp"

namespace mfem
{

MultigridOperator::MultigridOperator() {}

MultigridOperator::MultigridOperator(Operator* opr, Solver* coarseSolver,
                                     bool ownOperator, bool ownSolver)
{
   AddCoarsestLevel(opr, coarseSolver, ownOperator, ownSolver);
}

MultigridOperator::~MultigridOperator()
{
   for (int i = operators.Size() - 1; i >= 0; --i)
   {
      if (ownedOperators[i])
      {
         delete operators[i];
      }
      if (ownedSmoothers[i])
      {
         delete smoothers[i];
      }
   }

   for (int i = prolongations.Size() - 1; i >= 0; --i)
   {
      if (ownedProlongations[i])
      {
         delete prolongations[i];
      }
   }

   operators.DeleteAll();
   smoothers.DeleteAll();
}

void MultigridOperator::AddCoarsestLevel(Operator* opr, Solver* solver,
                                         bool ownOperator, bool ownSolver)
{
   MFEM_VERIFY(NumLevels() == 0, "Coarse level already exists");
   operators.Append(opr);
   smoothers.Append(solver);
   ownedOperators.Append(ownOperator);
   ownedSmoothers.Append(ownSolver);
   width = opr->Width();
   height = opr->Height();
}

void MultigridOperator::AddLevel(Operator* opr, Solver* smoother,
                                 const Operator* prolongation, bool ownOperator,
                                 bool ownSmoother, bool ownProlongation)
{
   MFEM_VERIFY(NumLevels() > 0, "Please add a coarse level first");
   operators.Append(opr);
   smoothers.Append(smoother);
   prolongations.Append(prolongation);
   ownedOperators.Append(ownOperator);
   ownedSmoothers.Append(ownSmoother);
   ownedProlongations.Append(ownProlongation);
   width = opr->Width();
   height = opr->Height();
}

int MultigridOperator::NumLevels() const { return operators.Size(); }

int MultigridOperator::GetFinestLevelIndex() const { return NumLevels() - 1; }

void MultigridOperator::MultAtLevel(int level, const Vector& x, Vector& y) const
{
   MFEM_ASSERT(level < NumLevels(), "Level does not exist.");
   operators[level]->Mult(x, y);
}

/// Matrix vector multiplication on finest level
void MultigridOperator::Mult(const Vector& x, Vector& y) const
{
   MFEM_ASSERT(NumLevels() > 0, "At least one level needs to exist.");
   MultAtLevel(NumLevels() - 1, x, y);
}

void MultigridOperator::RestrictTo(int level, const Vector& x, Vector& y) const
{
   prolongations[level]->MultTranspose(x, y);
}

void MultigridOperator::InterpolateFrom(int level, const Vector& x,
                                        Vector& y) const
{
   prolongations[level]->Mult(x, y);
}

void MultigridOperator::ApplySmootherAtLevel(int level, const Vector& x,
                                             Vector& y) const
{
   smoothers[level]->Mult(x, y);
}

const Operator* MultigridOperator::GetOperatorAtLevel(int level) const
{
   return operators[level];
}

Operator* MultigridOperator::GetOperatorAtLevel(int level)
{
   return operators[level];
}

const Operator* MultigridOperator::GetOperatorAtFinestLevel() const
{
   return GetOperatorAtLevel(operators.Size() - 1);
}

Operator* MultigridOperator::GetOperatorAtFinestLevel()
{
   return GetOperatorAtLevel(operators.Size() - 1);
}

Solver* MultigridOperator::GetSmootherAtLevel(int level) const
{
   return smoothers[level];
}

Solver* MultigridOperator::GetSmootherAtLevel(int level)
{
   return smoothers[level];
}

TimedMultigridOperator::TimedMultigridOperator() : MultigridOperator() {}

TimedMultigridOperator::TimedMultigridOperator(Operator* opr,
                                               Solver* coarseSolver,
                                               bool ownOperator, bool ownSolver)
   : MultigridOperator(opr, coarseSolver, ownOperator, ownSolver)
{
}

TimedMultigridOperator::~TimedMultigridOperator() {}

void TimedMultigridOperator::MultAtLevel(int level, const Vector& x,
                                         Vector& y) const
{
   MFEM_ASSERT(level < NumLevels(), "Level does not exist.");
   sw.Clear();
   sw.Start();
   operators[level]->Mult(x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::OPERATOR,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::OPERATOR, level)] +=
      sw.RealTime();
}

void TimedMultigridOperator::RestrictTo(int level, const Vector& x,
                                        Vector& y) const
{
   sw.Clear();
   sw.Start();
   prolongations[level]->MultTranspose(x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::RESTRICTION,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::RESTRICTION,
                         level)] += sw.RealTime();
}

void TimedMultigridOperator::InterpolateFrom(int level, const Vector& x,
                                             Vector& y) const
{
   sw.Clear();
   sw.Start();
   prolongations[level]->Mult(x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::PROLONGATION,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::PROLONGATION,
                         level)] += sw.RealTime();
}

void TimedMultigridOperator::ApplySmootherAtLevel(int level, const Vector& x,
                                                  Vector& y) const
{
   sw.Clear();
   sw.Start();
   MultigridOperator::ApplySmootherAtLevel(level, x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::SMOOTHER,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::SMOOTHER, level)] +=
      sw.RealTime();
}

void TimedMultigridOperator::PrintStats(Operation operation,
                                        std::ostream& out) const
{
   std::map<Operation, std::string> operationToString =
   {
      {Operation::OPERATOR, "Operator"},
      {Operation::PROLONGATION, "Prolongation"},
      {Operation::RESTRICTION, "Restriction"},
      {Operation::SMOOTHER, "Smoother"}
   };

   out << std::setw(5) << "Level";
   out << std::setw(16) << operationToString[operation] << "NA";
   out << std::setw(16) << operationToString[operation] << "TT";
   out << std::setw(16) << operationToString[operation] << "TPA";
   out << "\n";

   for (int level = 0; level < NumLevels(); ++level)
   {
      int numAppl =
         stats[std::make_tuple(Statistics::NUMAPPLICATIONS, operation, level)];
      double totalTime =
         stats[std::make_tuple(Statistics::TOTALTIME, operation, level)];
      double timePerAppl = (numAppl != 0) ? (totalTime / numAppl) : INFINITY;

      out << std::setw(5) << level;
      out << std::setw(18) << std::fixed << std::setprecision(3) << numAppl;
      out << std::setw(18) << std::fixed << std::setprecision(3) << totalTime;
      out << std::setw(19) << std::fixed << std::setprecision(3) << timePerAppl;
      out << "\n";
   }
}

MultigridSolver::MultigridSolver(const MultigridOperator* opr_,
                                 CycleType cycleType_, int preSmoothingSteps_,
                                 int postSmoothingSteps_)
   : opr(opr_), cycleType(cycleType_)
{
   Setup(preSmoothingSteps_, postSmoothingSteps_);
}

MultigridSolver::~MultigridSolver() { Reset(); }

void MultigridSolver::SetCycleType(CycleType cycleType_)
{
   cycleType = cycleType_;
}

void MultigridSolver::SetPreSmoothingSteps(int steps)
{
   preSmoothingSteps = steps;
}

void MultigridSolver::SetPreSmoothingSteps(const Array<int>& steps)
{
   MFEM_VERIFY(
      steps.Size() == preSmoothingSteps.Size(),
      "Number of step sizes needs to be the same as the number of levels");
   preSmoothingSteps = steps;
}

void MultigridSolver::SetPostSmoothingSteps(int steps)
{
   postSmoothingSteps = steps;
}

void MultigridSolver::SetPostSmoothingSteps(const Array<int>& steps)
{
   MFEM_VERIFY(
      steps.Size() == postSmoothingSteps.Size(),
      "Number of step sizes needs to be the same as the number of levels");
   postSmoothingSteps = steps;
}

void MultigridSolver::SetSmoothingSteps(int steps)
{
   SetPreSmoothingSteps(steps);
   SetPostSmoothingSteps(steps);
}

void MultigridSolver::SetSmoothingSteps(const Array<int>& steps)
{
   SetPreSmoothingSteps(steps);
   SetPostSmoothingSteps(steps);
}

void MultigridSolver::Mult(const Vector& x, Vector& y) const
{
   // Safe const_cast, since x at the finest level will never be modified
   X.Last() = const_cast<Vector*>(&x);
   y = 0.0;
   Y.Last() = &y;
   Cycle(opr->NumLevels() - 1);
   X.Last() = nullptr;
   Y.Last() = nullptr;
}

void MultigridSolver::SetOperator(const Operator& op)
{
   if (!dynamic_cast<const MultigridOperator*>(&op))
   {
      MFEM_ABORT("Unsupported operator for MultigridSolver");
   }

   Reset();
   opr = static_cast<const MultigridOperator*>(&op);
   Setup();
}

void MultigridSolver::SmoothingStep(int level) const
{
   opr->MultAtLevel(level, *Y[level], *R[level]);          // r = A x
   subtract(*X[level], *R[level], *R[level]);              // r = b - A x
   opr->ApplySmootherAtLevel(level, *R[level], *Z[level]); // z = S r
   add(*Y[level], 1.0, *Z[level], *Y[level]); // x = x + S (b - A x)
}

void MultigridSolver::Cycle(int level) const
{
   if (level == 0)
   {
      opr->ApplySmootherAtLevel(level, *X[level], *Y[level]);
      return;
   }

   for (int i = 0; i < preSmoothingSteps[level]; i++)
   {
      SmoothingStep(level);
   }

   // Compute residual
   opr->MultAtLevel(level, *Y[level], *R[level]);
   subtract(*X[level], *R[level], *R[level]);

   // Restrict residual
   opr->RestrictTo(level - 1, *R[level], *X[level - 1]);

   // Init zeros
   *Y[level - 1] = 0.0;

   // Corrections
   int corrections = 1;
   if (cycleType == CycleType::WCYCLE)
   {
      corrections = 2;
   }
   for (int correction = 0; correction < corrections; ++correction)
   {
      Cycle(level - 1);
   }

   // Prolongate
   opr->InterpolateFrom(level - 1, *Y[level - 1], *R[level]);

   // Add update
   *Y[level] += *R[level];

   // Post-smooth
   for (int i = 0; i < postSmoothingSteps[level]; i++)
   {
      SmoothingStep(level);
   }
}

void MultigridSolver::Setup(int preSmoothingSteps_, int postSmoothingSteps_)
{
   for (int level = 0; level < opr->NumLevels() - 1; ++level)
   {
      int vectorSize = opr->GetOperatorAtLevel(level)->Height();
      X.Append(new Vector(vectorSize));
      *X.Last() = 0.0;
      Y.Append(new Vector(vectorSize));
      *Y.Last() = 0.0;
      R.Append(new Vector(vectorSize));
      *R.Last() = 0.0;
      Z.Append(new Vector(vectorSize));
      *Z.Last() = 0.0;
   }

   // X and Y at the finest level will be filled by Mult
   X.Append(nullptr);
   Y.Append(nullptr);
   R.Append(new Vector(opr->GetOperatorAtFinestLevel()->Height()));
   *R.Last() = 0.0;
   Z.Append(new Vector(opr->GetOperatorAtFinestLevel()->Height()));
   *Z.Last() = 0.0;

   preSmoothingSteps.SetSize(opr->NumLevels());
   postSmoothingSteps.SetSize(opr->NumLevels());

   preSmoothingSteps = preSmoothingSteps_;
   postSmoothingSteps = postSmoothingSteps_;
}

void MultigridSolver::Reset()
{
   for (int i = 0; i < X.Size(); ++i)
   {
      delete X[i];
      delete Y[i];
      delete R[i];
      delete Z[i];
   }

   X.DeleteAll();
   Y.DeleteAll();
   R.DeleteAll();
   Z.DeleteAll();

   preSmoothingSteps.DeleteAll();
   postSmoothingSteps.DeleteAll();
}

} // namespace mfem
<commit_msg>Reversed order of deletions<commit_after>// Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
// the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
// reserved. See file COPYRIGHT for details.
//
// This file is part of the MFEM library. For more information and source code
// availability see http://mfem.org.
//
// MFEM 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) version 2.1 dated February 1999.

#include "multigrid.hpp"

namespace mfem
{

MultigridOperator::MultigridOperator() {}

MultigridOperator::MultigridOperator(Operator* opr, Solver* coarseSolver,
                                     bool ownOperator, bool ownSolver)
{
   AddCoarsestLevel(opr, coarseSolver, ownOperator, ownSolver);
}

MultigridOperator::~MultigridOperator()
{
   for (int i = 0; i < operators.Size(); ++i)
   {
      if (ownedOperators[i])
      {
         delete operators[i];
      }
      if (ownedSmoothers[i])
      {
         delete smoothers[i];
      }
   }

   for (int i = 0; i < prolongations.Size(); ++i)
   {
      if (ownedProlongations[i])
      {
         delete prolongations[i];
      }
   }

   operators.DeleteAll();
   smoothers.DeleteAll();
}

void MultigridOperator::AddCoarsestLevel(Operator* opr, Solver* solver,
                                         bool ownOperator, bool ownSolver)
{
   MFEM_VERIFY(NumLevels() == 0, "Coarse level already exists");
   operators.Append(opr);
   smoothers.Append(solver);
   ownedOperators.Append(ownOperator);
   ownedSmoothers.Append(ownSolver);
   width = opr->Width();
   height = opr->Height();
}

void MultigridOperator::AddLevel(Operator* opr, Solver* smoother,
                                 const Operator* prolongation, bool ownOperator,
                                 bool ownSmoother, bool ownProlongation)
{
   MFEM_VERIFY(NumLevels() > 0, "Please add a coarse level first");
   operators.Append(opr);
   smoothers.Append(smoother);
   prolongations.Append(prolongation);
   ownedOperators.Append(ownOperator);
   ownedSmoothers.Append(ownSmoother);
   ownedProlongations.Append(ownProlongation);
   width = opr->Width();
   height = opr->Height();
}

int MultigridOperator::NumLevels() const { return operators.Size(); }

int MultigridOperator::GetFinestLevelIndex() const { return NumLevels() - 1; }

void MultigridOperator::MultAtLevel(int level, const Vector& x, Vector& y) const
{
   MFEM_ASSERT(level < NumLevels(), "Level does not exist.");
   operators[level]->Mult(x, y);
}

/// Matrix vector multiplication on finest level
void MultigridOperator::Mult(const Vector& x, Vector& y) const
{
   MFEM_ASSERT(NumLevels() > 0, "At least one level needs to exist.");
   MultAtLevel(NumLevels() - 1, x, y);
}

void MultigridOperator::RestrictTo(int level, const Vector& x, Vector& y) const
{
   prolongations[level]->MultTranspose(x, y);
}

void MultigridOperator::InterpolateFrom(int level, const Vector& x,
                                        Vector& y) const
{
   prolongations[level]->Mult(x, y);
}

void MultigridOperator::ApplySmootherAtLevel(int level, const Vector& x,
                                             Vector& y) const
{
   smoothers[level]->Mult(x, y);
}

const Operator* MultigridOperator::GetOperatorAtLevel(int level) const
{
   return operators[level];
}

Operator* MultigridOperator::GetOperatorAtLevel(int level)
{
   return operators[level];
}

const Operator* MultigridOperator::GetOperatorAtFinestLevel() const
{
   return GetOperatorAtLevel(operators.Size() - 1);
}

Operator* MultigridOperator::GetOperatorAtFinestLevel()
{
   return GetOperatorAtLevel(operators.Size() - 1);
}

Solver* MultigridOperator::GetSmootherAtLevel(int level) const
{
   return smoothers[level];
}

Solver* MultigridOperator::GetSmootherAtLevel(int level)
{
   return smoothers[level];
}

TimedMultigridOperator::TimedMultigridOperator() : MultigridOperator() {}

TimedMultigridOperator::TimedMultigridOperator(Operator* opr,
                                               Solver* coarseSolver,
                                               bool ownOperator, bool ownSolver)
   : MultigridOperator(opr, coarseSolver, ownOperator, ownSolver)
{
}

TimedMultigridOperator::~TimedMultigridOperator() {}

void TimedMultigridOperator::MultAtLevel(int level, const Vector& x,
                                         Vector& y) const
{
   MFEM_ASSERT(level < NumLevels(), "Level does not exist.");
   sw.Clear();
   sw.Start();
   operators[level]->Mult(x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::OPERATOR,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::OPERATOR, level)] +=
      sw.RealTime();
}

void TimedMultigridOperator::RestrictTo(int level, const Vector& x,
                                        Vector& y) const
{
   sw.Clear();
   sw.Start();
   prolongations[level]->MultTranspose(x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::RESTRICTION,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::RESTRICTION,
                         level)] += sw.RealTime();
}

void TimedMultigridOperator::InterpolateFrom(int level, const Vector& x,
                                             Vector& y) const
{
   sw.Clear();
   sw.Start();
   prolongations[level]->Mult(x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::PROLONGATION,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::PROLONGATION,
                         level)] += sw.RealTime();
}

void TimedMultigridOperator::ApplySmootherAtLevel(int level, const Vector& x,
                                                  Vector& y) const
{
   sw.Clear();
   sw.Start();
   MultigridOperator::ApplySmootherAtLevel(level, x, y);
   sw.Stop();
   stats[std::make_tuple(Statistics::NUMAPPLICATIONS, Operation::SMOOTHER,
                         level)] += 1;
   stats[std::make_tuple(Statistics::TOTALTIME, Operation::SMOOTHER, level)] +=
      sw.RealTime();
}

void TimedMultigridOperator::PrintStats(Operation operation,
                                        std::ostream& out) const
{
   std::map<Operation, std::string> operationToString =
   {
      {Operation::OPERATOR, "Operator"},
      {Operation::PROLONGATION, "Prolongation"},
      {Operation::RESTRICTION, "Restriction"},
      {Operation::SMOOTHER, "Smoother"}
   };

   out << std::setw(5) << "Level";
   out << std::setw(16) << operationToString[operation] << "NA";
   out << std::setw(16) << operationToString[operation] << "TT";
   out << std::setw(16) << operationToString[operation] << "TPA";
   out << "\n";

   for (int level = 0; level < NumLevels(); ++level)
   {
      int numAppl =
         stats[std::make_tuple(Statistics::NUMAPPLICATIONS, operation, level)];
      double totalTime =
         stats[std::make_tuple(Statistics::TOTALTIME, operation, level)];
      double timePerAppl = (numAppl != 0) ? (totalTime / numAppl) : INFINITY;

      out << std::setw(5) << level;
      out << std::setw(18) << std::fixed << std::setprecision(3) << numAppl;
      out << std::setw(18) << std::fixed << std::setprecision(3) << totalTime;
      out << std::setw(19) << std::fixed << std::setprecision(3) << timePerAppl;
      out << "\n";
   }
}

MultigridSolver::MultigridSolver(const MultigridOperator* opr_,
                                 CycleType cycleType_, int preSmoothingSteps_,
                                 int postSmoothingSteps_)
   : opr(opr_), cycleType(cycleType_)
{
   Setup(preSmoothingSteps_, postSmoothingSteps_);
}

MultigridSolver::~MultigridSolver() { Reset(); }

void MultigridSolver::SetCycleType(CycleType cycleType_)
{
   cycleType = cycleType_;
}

void MultigridSolver::SetPreSmoothingSteps(int steps)
{
   preSmoothingSteps = steps;
}

void MultigridSolver::SetPreSmoothingSteps(const Array<int>& steps)
{
   MFEM_VERIFY(
      steps.Size() == preSmoothingSteps.Size(),
      "Number of step sizes needs to be the same as the number of levels");
   preSmoothingSteps = steps;
}

void MultigridSolver::SetPostSmoothingSteps(int steps)
{
   postSmoothingSteps = steps;
}

void MultigridSolver::SetPostSmoothingSteps(const Array<int>& steps)
{
   MFEM_VERIFY(
      steps.Size() == postSmoothingSteps.Size(),
      "Number of step sizes needs to be the same as the number of levels");
   postSmoothingSteps = steps;
}

void MultigridSolver::SetSmoothingSteps(int steps)
{
   SetPreSmoothingSteps(steps);
   SetPostSmoothingSteps(steps);
}

void MultigridSolver::SetSmoothingSteps(const Array<int>& steps)
{
   SetPreSmoothingSteps(steps);
   SetPostSmoothingSteps(steps);
}

void MultigridSolver::Mult(const Vector& x, Vector& y) const
{
   // Safe const_cast, since x at the finest level will never be modified
   X.Last() = const_cast<Vector*>(&x);
   y = 0.0;
   Y.Last() = &y;
   Cycle(opr->NumLevels() - 1);
   X.Last() = nullptr;
   Y.Last() = nullptr;
}

void MultigridSolver::SetOperator(const Operator& op)
{
   if (!dynamic_cast<const MultigridOperator*>(&op))
   {
      MFEM_ABORT("Unsupported operator for MultigridSolver");
   }

   Reset();
   opr = static_cast<const MultigridOperator*>(&op);
   Setup();
}

void MultigridSolver::SmoothingStep(int level) const
{
   opr->MultAtLevel(level, *Y[level], *R[level]);          // r = A x
   subtract(*X[level], *R[level], *R[level]);              // r = b - A x
   opr->ApplySmootherAtLevel(level, *R[level], *Z[level]); // z = S r
   add(*Y[level], 1.0, *Z[level], *Y[level]); // x = x + S (b - A x)
}

void MultigridSolver::Cycle(int level) const
{
   if (level == 0)
   {
      opr->ApplySmootherAtLevel(level, *X[level], *Y[level]);
      return;
   }

   for (int i = 0; i < preSmoothingSteps[level]; i++)
   {
      SmoothingStep(level);
   }

   // Compute residual
   opr->MultAtLevel(level, *Y[level], *R[level]);
   subtract(*X[level], *R[level], *R[level]);

   // Restrict residual
   opr->RestrictTo(level - 1, *R[level], *X[level - 1]);

   // Init zeros
   *Y[level - 1] = 0.0;

   // Corrections
   int corrections = 1;
   if (cycleType == CycleType::WCYCLE)
   {
      corrections = 2;
   }
   for (int correction = 0; correction < corrections; ++correction)
   {
      Cycle(level - 1);
   }

   // Prolongate
   opr->InterpolateFrom(level - 1, *Y[level - 1], *R[level]);

   // Add update
   *Y[level] += *R[level];

   // Post-smooth
   for (int i = 0; i < postSmoothingSteps[level]; i++)
   {
      SmoothingStep(level);
   }
}

void MultigridSolver::Setup(int preSmoothingSteps_, int postSmoothingSteps_)
{
   for (int level = 0; level < opr->NumLevels() - 1; ++level)
   {
      int vectorSize = opr->GetOperatorAtLevel(level)->Height();
      X.Append(new Vector(vectorSize));
      *X.Last() = 0.0;
      Y.Append(new Vector(vectorSize));
      *Y.Last() = 0.0;
      R.Append(new Vector(vectorSize));
      *R.Last() = 0.0;
      Z.Append(new Vector(vectorSize));
      *Z.Last() = 0.0;
   }

   // X and Y at the finest level will be filled by Mult
   X.Append(nullptr);
   Y.Append(nullptr);
   R.Append(new Vector(opr->GetOperatorAtFinestLevel()->Height()));
   *R.Last() = 0.0;
   Z.Append(new Vector(opr->GetOperatorAtFinestLevel()->Height()));
   *Z.Last() = 0.0;

   preSmoothingSteps.SetSize(opr->NumLevels());
   postSmoothingSteps.SetSize(opr->NumLevels());

   preSmoothingSteps = preSmoothingSteps_;
   postSmoothingSteps = postSmoothingSteps_;
}

void MultigridSolver::Reset()
{
   for (int i = 0; i < X.Size(); ++i)
   {
      delete X[i];
      delete Y[i];
      delete R[i];
      delete Z[i];
   }

   X.DeleteAll();
   Y.DeleteAll();
   R.DeleteAll();
   Z.DeleteAll();

   preSmoothingSteps.DeleteAll();
   postSmoothingSteps.DeleteAll();
}

} // namespace mfem
<|endoftext|>


<commit_before>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  David Shah <david@symbioticeda.com>
 *  Copyright (C) 2021  William D. Jones <wjones@wdj-consulting.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "bitstream.h"
#include "config.h"

NEXTPNR_NAMESPACE_BEGIN

void write_bitstream(Context *ctx, std::string text_config_file)
{
    ChipConfig cc;

}

NEXTPNR_NAMESPACE_END
<commit_msg>machxo2: Emit empty bitstream file.<commit_after>/*
 *  nextpnr -- Next Generation Place and Route
 *
 *  Copyright (C) 2018  David Shah <david@symbioticeda.com>
 *  Copyright (C) 2021  William D. Jones <wjones@wdj-consulting.com>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include <fstream>

#include "bitstream.h"
#include "config.h"

NEXTPNR_NAMESPACE_BEGIN

// These seem simple enough to do inline for now.
namespace BaseConfigs {
    void config_empty_lcmxo2_1200hc(ChipConfig &cc)
    {
        cc.chip_name = "LCMXO2-1200HC";

        cc.tiles["EBR_R6C11:EBR1"].add_unknown(0, 12);
        cc.tiles["EBR_R6C15:EBR1"].add_unknown(0, 12);
        cc.tiles["EBR_R6C18:EBR1"].add_unknown(0, 12);
        cc.tiles["EBR_R6C21:EBR1"].add_unknown(0, 12);
        cc.tiles["EBR_R6C2:EBR1"].add_unknown(0, 12);
        cc.tiles["EBR_R6C5:EBR1"].add_unknown(0, 12);
        cc.tiles["EBR_R6C8:EBR1"].add_unknown(0, 12);

        cc.tiles["PT4:CFG0"].add_unknown(5, 30);
        cc.tiles["PT4:CFG0"].add_unknown(5, 32);
        cc.tiles["PT4:CFG0"].add_unknown(5, 36);

        cc.tiles["PT7:CFG3"].add_unknown(5, 18);
    }
} // namespace BaseConfigs

void write_bitstream(Context *ctx, std::string text_config_file)
{
    ChipConfig cc;

    switch (ctx->args.type) {
    case ArchArgs::LCMXO2_1200HC:
        BaseConfigs::config_empty_lcmxo2_1200hc(cc);
        break;
    default:
        NPNR_ASSERT_FALSE("Unsupported device type");
    }

    // Configure chip
    if (!text_config_file.empty()) {
        std::ofstream out_config(text_config_file);
        out_config << cc;
    }
}

NEXTPNR_NAMESPACE_END
<|endoftext|>


<commit_before>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<commit_msg>--allow-empty_message<commit_after>/******************************************************************************
 *  Copyright (c) 2014 Jamis Hoo
 *  Distributed under the MIT license
 *  (See accompanying file LICENSE or copy at http://opensource.org/licenses/MIT)
 *
 *  Project:
 *  Filename: test.cc
 *  Version: 1.0
 *  Author: Jamis Hoo
 *  E-mail: hjm211324@gmail.com
 *  Date: Dec. 29, 2014
 *  Time: 11:10:09
 *  Description:
 *****************************************************************************/
#include <iostream>

int main() {
    std::cout << "Hello world!" << std::endl;

}

<|endoftext|>


<commit_before>#include "led-matrix.h"

#include <iostream>
#include <unistd.h>
#include <math.h>
#include <stdio.h>

using rgb_matrix::GPIO;
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;

class Ball {
	int r, g, b;
	float x, y, vx, vy;
public:
	static const int GRAVITY = -20;
	Ball(float x, float y, float vx, float vy, int r, int g, int b): x(x), y(y), vx(vx), vy(vy), r(r), g(g), b(b) {}
	void updateValues(float timeElapsed) {
		x += vx * timeElapsed;
		y += vy * timeElapsed + 0.5 * Ball::GRAVITY * pow(timeElapsed, 2);
		vy += Ball::GRAVITY * timeElapsed;
		edgeHandling(timeElapsed);
	}
	void edgeHandling(float timeElapsed) {
		if((int) y == 0) {
			vx -= copysign(1, vx) * timeElapsed;
		}

		if(x < 0) {
			vx = abs(vx);
			x = 0;
		}
		else if(x > 31) {
			vx = abs(vx) * -1;
			x = 31;
		}

		if(y < 0) {
			vy = abs(vy) * 0.95; // Bounce decay
			y = 0;
		}
		else if(y > 15) {
			vy = abs(vy) * -0.95; // Bounce decay
			y = 15;
		}
	}
	void drawOnCanvas(Canvas *canvas) {
		canvas->SetPixel((int) x, canvas->height() - 1 - (int) y, r, g, b);
	}
	void printValues() {
		std::cout << "x: " << x << " y: " << y << " vx: " << vx << " vy: " << vy << std::endl;
	}
};

static void DrawOnCanvas(Canvas *canvas) {
	Ball *red = new Ball(2, 12, 4, -4, 255, 0, 0);
	Ball *blue = new Ball(6, 9, 15, 12, 0, 0, 255);
	int c = 0;
	while(c < 60000) {
		red->updateValues(1 / 60.0);
		blue->updateValues(1 / 60.0);
		red->drawOnCanvas(canvas);
		blue->drawOnCanvas(canvas);
		c++;
		usleep(1000000 / 60.0);
		canvas->Clear();
	}
}

int main(int argc, char *argv[]) {
	GPIO io;
	if(!io.Init()) {
		return 1;
	}

	Canvas *canvas = new RGBMatrix(&io, 16, 1, 1);
	DrawOnCanvas(canvas);

	canvas->Clear();
	delete canvas;

	return 0;
}
<commit_msg>Add more balls<commit_after>#include "led-matrix.h"

#include <iostream>
#include <unistd.h>
#include <math.h>
#include <stdio.h>

using rgb_matrix::GPIO;
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;

class Ball {
	int r, g, b;
	float x, y, vx, vy;
public:
	static const int GRAVITY = -20;
	Ball(float x, float y, float vx, float vy, int r, int g, int b): x(x), y(y), vx(vx), vy(vy), r(r), g(g), b(b) {}
	void updateValues(float timeElapsed) {
		x += vx * timeElapsed;
		y += vy * timeElapsed + 0.5 * Ball::GRAVITY * pow(timeElapsed, 2);
		vy += Ball::GRAVITY * timeElapsed;
		edgeHandling(timeElapsed);
	}
	void edgeHandling(float timeElapsed) {
		if((int) y == 0) {
			vx -= copysign(1, vx) * timeElapsed;
		}

		if(x < 0) {
			vx = abs(vx);
			x = 0;
		}
		else if(x > 31) {
			vx = abs(vx) * -1;
			x = 31;
		}

		if(y < 0) {
			vy = abs(vy) * 0.95; // Bounce decay
			y = 0;
		}
		else if(y > 15) {
			vy = abs(vy) * -0.95; // Bounce decay
			y = 15;
		}
	}
	void drawOnCanvas(Canvas *canvas) {
		canvas->SetPixel((int) x, canvas->height() - 1 - (int) y, 0, (int) (x * 255 / 32), (int) (y * 255 / 16));
	}
	void printValues() {
		std::cout << "x: " << x << " y: " << y << " vx: " << vx << " vy: " << vy << std::endl;
	}
};

static void DrawOnCanvas(Canvas *canvas) {
	Ball *red = new Ball(2, 12, 4, -4, 255, 0, 0);
	Ball *blue = new Ball(6, 9, 15, 12, 0, 0, 255);
	Ball *b1 = new Ball(3, 2, -5, 3, 0, 0, 255);
	Ball *b2 = new Ball(4, 29, 2, 5, 0, 0, 255);
	int c = 0;
	while(c < 60000) {
		red->updateValues(1 / 60.0);
		blue->updateValues(1 / 60.0);
		b1->updateValues(1 / 60.0);
		b2->updateValues(1 / 60.0);
		red->drawOnCanvas(canvas);
		blue->drawOnCanvas(canvas);
		b1->drawOnCanvas(canvas);
		b2->drawOnCanvas(canvas);
		c++;
		usleep(1000000 / 60.0);
		canvas->Clear();
	}
}

int main(int argc, char *argv[]) {
	GPIO io;
	if(!io.Init()) {
		return 1;
	}

	Canvas *canvas = new RGBMatrix(&io, 16, 1, 1);
	DrawOnCanvas(canvas);

	canvas->Clear();
	delete canvas;

	return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/file_system/file_system_dispatcher_host.h"

#include "base/file_path.h"
#include "base/thread.h"
#include "base/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/file_system/browser_file_system_callback_dispatcher.h"
#include "chrome/browser/file_system/file_system_host_context.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "googleurl/src/gurl.h"

// A class to hold an ongoing openFileSystem completion task.
struct OpenFileSystemCompletionTask {
 public:
  static void Run(
      int request_id,
      const std::string& name,
      const FilePath& root_path,
      FileSystemDispatcherHost* dispatcher_host) {
    // The task is self-destructed.
    new OpenFileSystemCompletionTask(request_id, name, root_path,
        dispatcher_host);
  }

  void DidFinish(base::PlatformFileError error) {
    if (error == base::PLATFORM_FILE_OK)
      dispatcher_host_->Send(
          new ViewMsg_OpenFileSystemRequest_Complete(
              request_id_, true, name_, root_path_));
    else
      dispatcher_host_->Send(
          new ViewMsg_OpenFileSystemRequest_Complete(
              request_id_, false, std::string(), FilePath()));
    delete this;
  }

 private:
  OpenFileSystemCompletionTask(
      int request_id,
      const std::string& name,
      const FilePath& root_path,
      FileSystemDispatcherHost* dispatcher_host)
    : request_id_(request_id),
      name_(name),
      root_path_(root_path),
      dispatcher_host_(dispatcher_host),
      callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
    base::FileUtilProxy::CreateDirectory(
        ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE),
        root_path_, false, true, callback_factory_.NewCallback(
            &OpenFileSystemCompletionTask::DidFinish));
  }

  int request_id_;
  std::string name_;
  FilePath root_path_;
  scoped_refptr<FileSystemDispatcherHost> dispatcher_host_;
  base::ScopedCallbackFactory<OpenFileSystemCompletionTask> callback_factory_;
};

FileSystemDispatcherHost::FileSystemDispatcherHost(
    IPC::Message::Sender* sender,
    FileSystemHostContext* file_system_host_context,
    HostContentSettingsMap* host_content_settings_map)
    : message_sender_(sender),
      process_handle_(0),
      shutdown_(false),
      context_(file_system_host_context),
      host_content_settings_map_(host_content_settings_map) {
  DCHECK(message_sender_);
}

FileSystemDispatcherHost::~FileSystemDispatcherHost() {
}

void FileSystemDispatcherHost::Init(base::ProcessHandle process_handle) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  DCHECK(!shutdown_);
  DCHECK(!process_handle_);
  DCHECK(process_handle);
  process_handle_ = process_handle;
}

void FileSystemDispatcherHost::Shutdown() {
  message_sender_ = NULL;
  shutdown_ = true;
}

bool FileSystemDispatcherHost::OnMessageReceived(
    const IPC::Message& message, bool* message_was_ok) {
  DCHECK(!shutdown_);
  *message_was_ok = true;
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(FileSystemDispatcherHost, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(ViewHostMsg_OpenFileSystemRequest, OnOpenFileSystem)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Move, OnMove)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Copy, OnCopy)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Remove, OnRemove)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_ReadMetadata, OnReadMetadata)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Create, OnCreate)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Exists, OnExists)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_ReadDirectory, OnReadDirectory)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Write, OnWrite)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Truncate, OnTruncate)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_TouchFile, OnTouchFile)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_CancelWrite, OnCancel)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP_EX()
  return handled;
}

void FileSystemDispatcherHost::OnOpenFileSystem(
    int request_id, const GURL& origin_url, fileapi::FileSystemType type,
    int64 requested_size) {

  // TODO(kinuko): hook up ContentSettings cookies type checks.

  FilePath root_path;
  std::string name;

  if (!context_->GetFileSystemRootPath(origin_url,
                                       type,
                                       &root_path,
                                       &name)) {
    Send(new ViewMsg_OpenFileSystemRequest_Complete(
        request_id,
        false,
        std::string(),
        FilePath()));
    return;
  }

  // Run the completion task that creates the root directory and sends
  // back the status code to the dispatcher.
  OpenFileSystemCompletionTask::Run(request_id, name, root_path, this);
}

void FileSystemDispatcherHost::OnMove(
    int request_id, const FilePath& src_path, const FilePath& dest_path) {
  if (!CheckValidFileSystemPath(src_path, request_id) ||
      !CheckValidFileSystemPath(dest_path, request_id))
    return;

  GetNewOperation(request_id)->Move(src_path, dest_path);
}

void FileSystemDispatcherHost::OnCopy(
    int request_id, const FilePath& src_path, const FilePath& dest_path) {
  if (!CheckValidFileSystemPath(src_path, request_id) ||
      !CheckValidFileSystemPath(dest_path, request_id))
    return;

  GetNewOperation(request_id)->Copy(src_path, dest_path);
}

void FileSystemDispatcherHost::OnRemove(int request_id, const FilePath& path) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->Remove(path);
}

void FileSystemDispatcherHost::OnReadMetadata(
    int request_id, const FilePath& path) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->GetMetadata(path);
}

void FileSystemDispatcherHost::OnCreate(
    int request_id, const FilePath& path, bool exclusive,
    bool is_directory, bool recursive) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  if (is_directory)
    GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive);
  else
    GetNewOperation(request_id)->CreateFile(path, exclusive);
}

void FileSystemDispatcherHost::OnExists(
    int request_id, const FilePath& path, bool is_directory) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  if (is_directory)
    GetNewOperation(request_id)->DirectoryExists(path);
  else
    GetNewOperation(request_id)->FileExists(path);
}

void FileSystemDispatcherHost::OnReadDirectory(
    int request_id, const FilePath& path) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->ReadDirectory(path);
}

void FileSystemDispatcherHost::OnWrite(
    int request_id,
    const FilePath& path,
    const GURL& blob_url,
    int64 offset) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->Write(path, blob_url, offset);
}

void FileSystemDispatcherHost::OnTruncate(
    int request_id,
    const FilePath& path,
    int64 length) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->Truncate(path, length);
}

void FileSystemDispatcherHost::OnTouchFile(
    int request_id,
    const FilePath& path,
    const base::Time& last_access_time,
    const base::Time& last_modified_time) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->TouchFile(
      path, last_access_time, last_modified_time);
}

void FileSystemDispatcherHost::OnCancel(
    int request_id,
    int request_id_to_cancel) {
  fileapi::FileSystemOperation* write =
      operations_.Lookup(request_id_to_cancel);
  if (write) {
    // The cancel will eventually send both the write failure and the cancel
    // success.
    write->Cancel(GetNewOperation(request_id));
  } else {
    // The write already finished; report that we failed to stop it.
    Send(new ViewMsg_FileSystem_DidFail(
        request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
  }
}

void FileSystemDispatcherHost::Send(IPC::Message* message) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (!shutdown_ && message_sender_)
    message_sender_->Send(message);
  else
    delete message;
}

bool FileSystemDispatcherHost::CheckValidFileSystemPath(
    const FilePath& path, int request_id) {
  // We may want do more checks, but for now it just checks if the given
  // |path| is under the valid FileSystem root path for this host context.
  if (!context_->CheckValidFileSystemPath(path)) {
    Send(new ViewMsg_FileSystem_DidFail(
        request_id, base::PLATFORM_FILE_ERROR_SECURITY));
    return false;
  }
  return true;
}

fileapi::FileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
    int request_id) {
  BrowserFileSystemCallbackDispatcher* dispatcher =
      new BrowserFileSystemCallbackDispatcher(this, request_id);
  fileapi::FileSystemOperation* operation = new fileapi::FileSystemOperation(
      dispatcher,
      ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE));
  operations_.AddWithID(operation, request_id);
  return operation;
}

void FileSystemDispatcherHost::RemoveCompletedOperation(int request_id) {
  DCHECK(operations_.Lookup(request_id));
  operations_.Remove(request_id);
}
<commit_msg>Hook up Cookies content settings for FileSystem API<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/file_system/file_system_dispatcher_host.h"

#include "base/file_path.h"
#include "base/thread.h"
#include "base/time.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/file_system/browser_file_system_callback_dispatcher.h"
#include "chrome/browser/file_system/file_system_host_context.h"
#include "chrome/browser/host_content_settings_map.h"
#include "chrome/browser/renderer_host/browser_render_process_host.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "googleurl/src/gurl.h"

// A class to hold an ongoing openFileSystem completion task.
struct OpenFileSystemCompletionTask {
 public:
  static void Run(
      int request_id,
      const std::string& name,
      const FilePath& root_path,
      FileSystemDispatcherHost* dispatcher_host) {
    // The task is self-destructed.
    new OpenFileSystemCompletionTask(request_id, name, root_path,
        dispatcher_host);
  }

  void DidFinish(base::PlatformFileError error) {
    if (error == base::PLATFORM_FILE_OK)
      dispatcher_host_->Send(
          new ViewMsg_OpenFileSystemRequest_Complete(
              request_id_, true, name_, root_path_));
    else
      dispatcher_host_->Send(
          new ViewMsg_OpenFileSystemRequest_Complete(
              request_id_, false, std::string(), FilePath()));
    delete this;
  }

 private:
  OpenFileSystemCompletionTask(
      int request_id,
      const std::string& name,
      const FilePath& root_path,
      FileSystemDispatcherHost* dispatcher_host)
    : request_id_(request_id),
      name_(name),
      root_path_(root_path),
      dispatcher_host_(dispatcher_host),
      callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
    base::FileUtilProxy::CreateDirectory(
        ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE),
        root_path_, false, true, callback_factory_.NewCallback(
            &OpenFileSystemCompletionTask::DidFinish));
  }

  int request_id_;
  std::string name_;
  FilePath root_path_;
  scoped_refptr<FileSystemDispatcherHost> dispatcher_host_;
  base::ScopedCallbackFactory<OpenFileSystemCompletionTask> callback_factory_;
};

FileSystemDispatcherHost::FileSystemDispatcherHost(
    IPC::Message::Sender* sender,
    FileSystemHostContext* file_system_host_context,
    HostContentSettingsMap* host_content_settings_map)
    : message_sender_(sender),
      process_handle_(0),
      shutdown_(false),
      context_(file_system_host_context),
      host_content_settings_map_(host_content_settings_map) {
  DCHECK(message_sender_);
}

FileSystemDispatcherHost::~FileSystemDispatcherHost() {
}

void FileSystemDispatcherHost::Init(base::ProcessHandle process_handle) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  DCHECK(!shutdown_);
  DCHECK(!process_handle_);
  DCHECK(process_handle);
  process_handle_ = process_handle;
}

void FileSystemDispatcherHost::Shutdown() {
  message_sender_ = NULL;
  shutdown_ = true;
}

bool FileSystemDispatcherHost::OnMessageReceived(
    const IPC::Message& message, bool* message_was_ok) {
  DCHECK(!shutdown_);
  *message_was_ok = true;
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(FileSystemDispatcherHost, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(ViewHostMsg_OpenFileSystemRequest, OnOpenFileSystem)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Move, OnMove)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Copy, OnCopy)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Remove, OnRemove)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_ReadMetadata, OnReadMetadata)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Create, OnCreate)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Exists, OnExists)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_ReadDirectory, OnReadDirectory)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Write, OnWrite)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_Truncate, OnTruncate)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_TouchFile, OnTouchFile)
    IPC_MESSAGE_HANDLER(ViewHostMsg_FileSystem_CancelWrite, OnCancel)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP_EX()
  return handled;
}

void FileSystemDispatcherHost::OnOpenFileSystem(
    int request_id, const GURL& origin_url, fileapi::FileSystemType type,
    int64 requested_size) {
  ContentSetting content_setting =
      host_content_settings_map_->GetContentSetting(
          origin_url, CONTENT_SETTINGS_TYPE_COOKIES, "");
  DCHECK((content_setting == CONTENT_SETTING_ALLOW) ||
         (content_setting == CONTENT_SETTING_BLOCK) ||
         (content_setting == CONTENT_SETTING_SESSION_ONLY));
  if (content_setting == CONTENT_SETTING_BLOCK) {
    // TODO(kinuko): Need to notify the UI thread to indicate that
    // there's a blocked content.
    Send(new ViewMsg_OpenFileSystemRequest_Complete(
        request_id, false, std::string(), FilePath()));
    return;
  }

  FilePath root_path;
  std::string name;
  if (!context_->GetFileSystemRootPath(origin_url, type, &root_path, &name)) {
    Send(new ViewMsg_OpenFileSystemRequest_Complete(
        request_id, false, std::string(), FilePath()));
    return;
  }

  // Run the completion task that creates the root directory and sends
  // back the status code to the dispatcher.
  OpenFileSystemCompletionTask::Run(request_id, name, root_path, this);
}

void FileSystemDispatcherHost::OnMove(
    int request_id, const FilePath& src_path, const FilePath& dest_path) {
  if (!CheckValidFileSystemPath(src_path, request_id) ||
      !CheckValidFileSystemPath(dest_path, request_id))
    return;

  GetNewOperation(request_id)->Move(src_path, dest_path);
}

void FileSystemDispatcherHost::OnCopy(
    int request_id, const FilePath& src_path, const FilePath& dest_path) {
  if (!CheckValidFileSystemPath(src_path, request_id) ||
      !CheckValidFileSystemPath(dest_path, request_id))
    return;

  GetNewOperation(request_id)->Copy(src_path, dest_path);
}

void FileSystemDispatcherHost::OnRemove(int request_id, const FilePath& path) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->Remove(path);
}

void FileSystemDispatcherHost::OnReadMetadata(
    int request_id, const FilePath& path) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->GetMetadata(path);
}

void FileSystemDispatcherHost::OnCreate(
    int request_id, const FilePath& path, bool exclusive,
    bool is_directory, bool recursive) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  if (is_directory)
    GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive);
  else
    GetNewOperation(request_id)->CreateFile(path, exclusive);
}

void FileSystemDispatcherHost::OnExists(
    int request_id, const FilePath& path, bool is_directory) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  if (is_directory)
    GetNewOperation(request_id)->DirectoryExists(path);
  else
    GetNewOperation(request_id)->FileExists(path);
}

void FileSystemDispatcherHost::OnReadDirectory(
    int request_id, const FilePath& path) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->ReadDirectory(path);
}

void FileSystemDispatcherHost::OnWrite(
    int request_id,
    const FilePath& path,
    const GURL& blob_url,
    int64 offset) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->Write(path, blob_url, offset);
}

void FileSystemDispatcherHost::OnTruncate(
    int request_id,
    const FilePath& path,
    int64 length) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->Truncate(path, length);
}

void FileSystemDispatcherHost::OnTouchFile(
    int request_id,
    const FilePath& path,
    const base::Time& last_access_time,
    const base::Time& last_modified_time) {
  if (!CheckValidFileSystemPath(path, request_id))
    return;
  GetNewOperation(request_id)->TouchFile(
      path, last_access_time, last_modified_time);
}

void FileSystemDispatcherHost::OnCancel(
    int request_id,
    int request_id_to_cancel) {
  fileapi::FileSystemOperation* write =
      operations_.Lookup(request_id_to_cancel);
  if (write) {
    // The cancel will eventually send both the write failure and the cancel
    // success.
    write->Cancel(GetNewOperation(request_id));
  } else {
    // The write already finished; report that we failed to stop it.
    Send(new ViewMsg_FileSystem_DidFail(
        request_id, base::PLATFORM_FILE_ERROR_INVALID_OPERATION));
  }
}

void FileSystemDispatcherHost::Send(IPC::Message* message) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
  if (!shutdown_ && message_sender_)
    message_sender_->Send(message);
  else
    delete message;
}

bool FileSystemDispatcherHost::CheckValidFileSystemPath(
    const FilePath& path, int request_id) {
  // We may want do more checks, but for now it just checks if the given
  // |path| is under the valid FileSystem root path for this host context.
  if (!context_->CheckValidFileSystemPath(path)) {
    Send(new ViewMsg_FileSystem_DidFail(
        request_id, base::PLATFORM_FILE_ERROR_SECURITY));
    return false;
  }
  return true;
}

fileapi::FileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
    int request_id) {
  BrowserFileSystemCallbackDispatcher* dispatcher =
      new BrowserFileSystemCallbackDispatcher(this, request_id);
  fileapi::FileSystemOperation* operation = new fileapi::FileSystemOperation(
      dispatcher,
      ChromeThread::GetMessageLoopProxyForThread(ChromeThread::FILE));
  operations_.AddWithID(operation, request_id);
  return operation;
}

void FileSystemDispatcherHost::RemoveCompletedOperation(int request_id) {
  DCHECK(operations_.Lookup(request_id));
  operations_.Remove(request_id);
}
<|endoftext|>


<commit_before><commit_msg>Render Helper would die in HandleLocaltime if passed an invalid time. Check the output of localtime() before using it.<commit_after><|endoftext|>


<commit_before>/* linbox/blackbox/triplesbb.inl
 * Copyright (c) Linbox
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========

 * Written by Rich Seagraves <seagrave@cis.udel.edu>
 * with mods by bds
 */

/** @file blackbox/triplesbb.h
 * @ingroup blackbox
 * @brief NO DOC
 */

#ifndef __LINBOX_triplesbb_INL
#define __LINBOX_triplesbb_INL

#include <algorithm>
#include <iostream>
using std::istream;
using std::ostream;
#include "linbox-config.h"
#include "linbox/util/debug.h"
#include "linbox/util/field-axpy.h"
#include "linbox/blackbox/blackbox-interface.h"
#include "linbox/field/hom.h"
#include "linbox/util/matrix-stream.h"

#include <omp.h>

#include <vector>

namespace LinBox
{

template<class MatDom> TriplesBB<MatDom>::
TriplesBB() {}

template<class MatDom> TriplesBB<MatDom>::
~TriplesBB() {}

template<class MatDom> TriplesBB<MatDom>::
TriplesBB(const Field& F, istream& in) : field_(&F), MD_(F) { read(in); }

template<class MatDom> istream& TriplesBB<MatDom>::
read(istream& in){
	Index r, c;
	typename Field::Element v; field().init(v);
	MatrixStream<Field> ms(field(), in);
	ms.getDimensions(r, c);
	init(field(), r, c);
	while (ms.nextTriple(r, c, v)) setEntry(r, c, v);
	return in;
}

template<class MatDom> ostream& TriplesBB<MatDom>::
write(ostream& out){
	Index r, c;
	out << "%%MatrixMarket matrix coordinate integer general" << std::endl;
	out << "% written from a LinBox TriplesBB" << std::endl;
	out << rowdim() <<" " << coldim() << " " << size() << std::endl;
	for (Index k = 0; k < size(); ++k) {
		Triple t = data_[k];
		field().write(out << t.row+1 << " " << t.col+1 << " ", t.elt) << std::endl;
	}
	return out;
}

template<class MatDom> TriplesBB<MatDom>& TriplesBB<MatDom>::
init(const Field& F, Index r, Index c)
{ field_ = &F; MD_.init(F), data_.clear(); rows_ = r; cols_ = c; rowMajor_ = 0; return *this; }

template<class MatDom> TriplesBB<MatDom>::
TriplesBB(const Field& F, Index r, Index c)
: field_(&F), data_(), rows_(r), cols_(c), rowMajor_(0) {}

template<class MatDom> TriplesBB<MatDom>::
TriplesBB(const TriplesBB<MatDom> & B)
: field_ ( B.field_ ), MD_(B.field()), data_ ( B.data_ ), rows_ ( B.rows_ ), cols_ ( B.cols_ ),
   rowMajor_ ( B.rowMajor_ )
{}

template<class MatDom> TriplesBB<MatDom>& TriplesBB<MatDom>::
operator=(const TriplesBB<MatDom> & rhs)
{	if (rhs == this) return ;
	field_ = rhs.field_;
	MD_.init(rhs.field_);
	data_ = rhs.data_;
	rows_ = rhs.rows_;
	cols_ = rhs.cols_;
	rowMajor_ = rhs.rowMajor_;
	return *this;
}

template<class MatDom> typename TriplesBB<MatDom>::Matrix& TriplesBB<MatDom>::
apply_left // Y = AX
	( typename TriplesBB<MatDom>::Matrix &Y,
	  const typename TriplesBB<MatDom>::Matrix &X
	) const
{	Y.zero();
	typename MatrixDomain::Submatrix Yc, Xc;// col submatrices
	for (Index k = 0; k < data_.size(); ++k) {
		Triple t = data_[k];
		Yc.submatrix(Y,t.row,0,1,Y.coldim());
		Xc.submatrix(X,t.col,0,1,X.coldim());
		MD_.axpyin(Yc, t.elt, Xc);
	}
	return Y;
}

template<class MatDom> typename TriplesBB<MatDom>::Matrix& TriplesBB<MatDom>::
apply_right // Y = XA
	( typename TriplesBB<MatDom>::Matrix &Y,
	  const typename TriplesBB<MatDom>::Matrix &X
	) const
{	Y.zero();
	typename MatrixDomain::Submatrix Yr, Xr; // row submatrices
	for (Index k = 0; k < data_.size(); ++k) {
		Triple t = data_[k];
		Yr.submatrix(Y,0,t.col,Y.rowdim(),1);
		Xr.submatrix(X,0,t.row,X.rowdim(),1);
		MD_.axpyin(Yr, t.elt, Xr);
	}
	return Y;
}

template<class MatDom>
template<class OutVector, class InVector>
OutVector & TriplesBB<MatDom>::apply(OutVector & y, const InVector & x) const
{
	linbox_check( rowdim() == y.size() );
	linbox_check( coldim() == x.size() );
        double start = omp_get_wtime();
	for (Index i = 0; i < y.size(); ++i) field().init(y[i], field().zero);
	for (Index k = 0; k < data_.size(); ++k) {
		Triple t = data_[k];
		field().axpyin(y[t.row], t.elt, x[t.col]);
	}
	return y;
}

template<class MatDom>
template<class OutVector, class InVector>
OutVector & TriplesBB<MatDom>::applyTranspose(OutVector & y, const InVector & x) const
{
	linbox_check( coldim() == y.size() );
	linbox_check( rowdim() == x.size() );
	for (Index i = 0; i < y.size(); ++i) field().init(y[i], field().zero);
	for (Index k = 0; k < data_.size(); ++k) {
		const Triple& t = data_[k];
		field().axpyin(y[t.col], t.elt, x[t.row]);
	}
	return y;
}

template<class MatDom> size_t TriplesBB<MatDom>::
rowdim() const { return rows_; }

template<class MatDom> size_t TriplesBB<MatDom>::
coldim() const { return cols_; }

template<class MatDom> const typename MatDom::Field& TriplesBB<MatDom>::
field() const { return *field_; }

template<class MatDom> const MatDom& TriplesBB<MatDom>::
domain() const { return MD_; }

template<class MatDom> size_t TriplesBB<MatDom>::
size() const { return data_.size(); }

template<class MatDom> void TriplesBB<MatDom>::
setEntry(Index i, Index j, const typename Field::Element & e)
{
	rowMajor_ = false;
	data_.push_back(Triple(i, j, e));
}

template<class MatDom> typename MatDom::Field::Element& TriplesBB<MatDom>::
getEntry(typename Field::Element& e, Index i, Index j) const
{
	for (Index k = 0; k < data_.size(); ++k)
		if (data_[k].row == i and data_[k].col == j)
			return e = data_[k].elt;
	return e = field().zero;
}

} // namespace LinBox

#endif // __LINBOX_triplesbb_INL

// Local Variables:
// mode: C++
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 8
// End:
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<commit_msg>Removed a line left in by mistake from triplesbb<commit_after>/* linbox/blackbox/triplesbb.inl
 * Copyright (c) Linbox
 * ========LICENCE========
 * This file is part of the library LinBox.
 *
 * LinBox 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * ========LICENCE========

 * Written by Rich Seagraves <seagrave@cis.udel.edu>
 * with mods by bds
 */

/** @file blackbox/triplesbb.h
 * @ingroup blackbox
 * @brief NO DOC
 */

#ifndef __LINBOX_triplesbb_INL
#define __LINBOX_triplesbb_INL

#include <algorithm>
#include <iostream>
using std::istream;
using std::ostream;
#include "linbox-config.h"
#include "linbox/util/debug.h"
#include "linbox/util/field-axpy.h"
#include "linbox/blackbox/blackbox-interface.h"
#include "linbox/field/hom.h"
#include "linbox/util/matrix-stream.h"

#include <omp.h>

#include <vector>

namespace LinBox
{

template<class MatDom> TriplesBB<MatDom>::
TriplesBB() {}

template<class MatDom> TriplesBB<MatDom>::
~TriplesBB() {}

template<class MatDom> TriplesBB<MatDom>::
TriplesBB(const Field& F, istream& in) : field_(&F), MD_(F) { read(in); }

template<class MatDom> istream& TriplesBB<MatDom>::
read(istream& in){
	Index r, c;
	typename Field::Element v; field().init(v);
	MatrixStream<Field> ms(field(), in);
	ms.getDimensions(r, c);
	init(field(), r, c);
	while (ms.nextTriple(r, c, v)) setEntry(r, c, v);
	return in;
}

template<class MatDom> ostream& TriplesBB<MatDom>::
write(ostream& out){
	Index r, c;
	out << "%%MatrixMarket matrix coordinate integer general" << std::endl;
	out << "% written from a LinBox TriplesBB" << std::endl;
	out << rowdim() <<" " << coldim() << " " << size() << std::endl;
	for (Index k = 0; k < size(); ++k) {
		Triple t = data_[k];
		field().write(out << t.row+1 << " " << t.col+1 << " ", t.elt) << std::endl;
	}
	return out;
}

template<class MatDom> TriplesBB<MatDom>& TriplesBB<MatDom>::
init(const Field& F, Index r, Index c)
{ field_ = &F; MD_.init(F), data_.clear(); rows_ = r; cols_ = c; rowMajor_ = 0; return *this; }

template<class MatDom> TriplesBB<MatDom>::
TriplesBB(const Field& F, Index r, Index c)
: field_(&F), data_(), rows_(r), cols_(c), rowMajor_(0) {}

template<class MatDom> TriplesBB<MatDom>::
TriplesBB(const TriplesBB<MatDom> & B)
: field_ ( B.field_ ), MD_(B.field()), data_ ( B.data_ ), rows_ ( B.rows_ ), cols_ ( B.cols_ ),
   rowMajor_ ( B.rowMajor_ )
{}

template<class MatDom> TriplesBB<MatDom>& TriplesBB<MatDom>::
operator=(const TriplesBB<MatDom> & rhs)
{	if (rhs == this) return ;
	field_ = rhs.field_;
	MD_.init(rhs.field_);
	data_ = rhs.data_;
	rows_ = rhs.rows_;
	cols_ = rhs.cols_;
	rowMajor_ = rhs.rowMajor_;
	return *this;
}

template<class MatDom> typename TriplesBB<MatDom>::Matrix& TriplesBB<MatDom>::
apply_left // Y = AX
	( typename TriplesBB<MatDom>::Matrix &Y,
	  const typename TriplesBB<MatDom>::Matrix &X
	) const
{	Y.zero();
	typename MatrixDomain::Submatrix Yc, Xc;// col submatrices
	for (Index k = 0; k < data_.size(); ++k) {
		Triple t = data_[k];
		Yc.submatrix(Y,t.row,0,1,Y.coldim());
		Xc.submatrix(X,t.col,0,1,X.coldim());
		MD_.axpyin(Yc, t.elt, Xc);
	}
	return Y;
}

template<class MatDom> typename TriplesBB<MatDom>::Matrix& TriplesBB<MatDom>::
apply_right // Y = XA
	( typename TriplesBB<MatDom>::Matrix &Y,
	  const typename TriplesBB<MatDom>::Matrix &X
	) const
{	Y.zero();
	typename MatrixDomain::Submatrix Yr, Xr; // row submatrices
	for (Index k = 0; k < data_.size(); ++k) {
		Triple t = data_[k];
		Yr.submatrix(Y,0,t.col,Y.rowdim(),1);
		Xr.submatrix(X,0,t.row,X.rowdim(),1);
		MD_.axpyin(Yr, t.elt, Xr);
	}
	return Y;
}

template<class MatDom>
template<class OutVector, class InVector>
OutVector & TriplesBB<MatDom>::apply(OutVector & y, const InVector & x) const
{
	linbox_check( rowdim() == y.size() );
	linbox_check( coldim() == x.size() );
	for (Index i = 0; i < y.size(); ++i) field().init(y[i], field().zero);
	for (Index k = 0; k < data_.size(); ++k) {
		Triple t = data_[k];
		field().axpyin(y[t.row], t.elt, x[t.col]);
	}
	return y;
}

template<class MatDom>
template<class OutVector, class InVector>
OutVector & TriplesBB<MatDom>::applyTranspose(OutVector & y, const InVector & x) const
{
	linbox_check( coldim() == y.size() );
	linbox_check( rowdim() == x.size() );
	for (Index i = 0; i < y.size(); ++i) field().init(y[i], field().zero);
	for (Index k = 0; k < data_.size(); ++k) {
		const Triple& t = data_[k];
		field().axpyin(y[t.col], t.elt, x[t.row]);
	}
	return y;
}

template<class MatDom> size_t TriplesBB<MatDom>::
rowdim() const { return rows_; }

template<class MatDom> size_t TriplesBB<MatDom>::
coldim() const { return cols_; }

template<class MatDom> const typename MatDom::Field& TriplesBB<MatDom>::
field() const { return *field_; }

template<class MatDom> const MatDom& TriplesBB<MatDom>::
domain() const { return MD_; }

template<class MatDom> size_t TriplesBB<MatDom>::
size() const { return data_.size(); }

template<class MatDom> void TriplesBB<MatDom>::
setEntry(Index i, Index j, const typename Field::Element & e)
{
	rowMajor_ = false;
	data_.push_back(Triple(i, j, e));
}

template<class MatDom> typename MatDom::Field::Element& TriplesBB<MatDom>::
getEntry(typename Field::Element& e, Index i, Index j) const
{
	for (Index k = 0; k < data_.size(); ++k)
		if (data_[k].row == i and data_[k].col == j)
			return e = data_[k].elt;
	return e = field().zero;
}

} // namespace LinBox

#endif // __LINBOX_triplesbb_INL

// Local Variables:
// mode: C++
// tab-width: 8
// indent-tabs-mode: nil
// c-basic-offset: 8
// End:
// vim:sts=8:sw=8:ts=8:noet:sr:cino=>s,f0,{0,g0,(0,\:0,t0,+0,=s
<|endoftext|>