<commit_before>/*
 * Copyright 2010-2016 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
 */

#include <memory.h>

#include "entry_p.h"
#include "input.h"
#include "cmd.h"

#include <bx/allocator.h>
#include <bx/ringbuffer.h>
#include <tinystl/allocator.h>
#include <tinystl/unordered_map.h>
namespace stl = tinystl;

struct Mouse
{
	Mouse()
		: m_width(1280)
		, m_height(720)
		, m_wheelDelta(120)
		, m_lock(false)
	{
	}

	void reset()
	{
		if (m_lock)
		{
			m_norm[0] = 0.0f;
			m_norm[1] = 0.0f;
			m_norm[2] = 0.0f;
		}

		memset(m_buttons, 0, sizeof(m_buttons) );
	}

	void setResolution(uint16_t _width, uint16_t _height)
	{
		m_width = _width;
		m_height = _height;
	}

	void setPos(int32_t _mx, int32_t _my, int32_t _mz)
	{
		m_absolute[0] = _mx;
		m_absolute[1] = _my;
		m_absolute[2] = _mz;
		m_norm[0] = float(_mx)/float(m_width);
		m_norm[1] = float(_my)/float(m_height);
		m_norm[2] = float(_mz)/float(m_wheelDelta);
	}

	void setButtonState(entry::MouseButton::Enum _button, uint8_t _state)
	{
		m_buttons[_button] = _state;
	}

	int32_t m_absolute[3];
	float m_norm[3];
	int32_t m_wheel;
	uint8_t m_buttons[entry::MouseButton::Count];
	uint16_t m_width;
	uint16_t m_height;
	uint16_t m_wheelDelta;
	bool m_lock;
};

struct Keyboard
{
	Keyboard()
		: m_ring(BX_COUNTOF(m_char) )
	{
	}

	void reset()
	{
		memset(m_key, 0, sizeof(m_key) );
		memset(m_once, 0xff, sizeof(m_once) );
	}

	static uint32_t encodeKeyState(uint8_t _modifiers, bool _down)
	{
		uint32_t state = 0;
		state |= uint32_t(_modifiers)<<16;
		state |= uint32_t(_down)<<8;
		return state;
	}

	static bool decodeKeyState(uint32_t _state, uint8_t& _modifiers)
	{
		_modifiers = (_state>>16)&0xff;
		return 0 != ( (_state>> 8)&0xff);
	}

	void setKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
	{
		m_key[_key] = encodeKeyState(_modifiers, _down);
		m_once[_key] = false;
	}

	bool getKeyState(entry::Key::Enum _key, uint8_t* _modifiers)
	{
		uint8_t modifiers;
		_modifiers = NULL == _modifiers ? &modifiers : _modifiers;

		return decodeKeyState(m_key[_key], *_modifiers);
	}

	uint8_t getModifiersState()
	{
		uint8_t modifiers = 0;
		for (uint32_t ii = 0; ii < entry::Key::Count; ++ii)
		{
			modifiers |= (m_key[ii]>>16)&0xff;
		}
		return modifiers;
	}

	void pushChar(uint8_t _len, const uint8_t _char[4])
	{
		for (uint32_t len = m_ring.reserve(4)
			; len < _len
			; len = m_ring.reserve(4)
			)
		{
			popChar();
		}

		memcpy(&m_char[m_ring.m_current], _char, 4);
		m_ring.commit(4);
	}

	const uint8_t* popChar()
	{
		if (0 < m_ring.available() )
		{
			uint8_t* utf8 = &m_char[m_ring.m_read];
			m_ring.consume(4);
			return utf8;
		}

		return NULL;
	}

	void charFlush()
	{
		m_ring.m_current = 0;
		m_ring.m_write   = 0;
		m_ring.m_read    = 0;
	}

	uint32_t m_key[256];
	bool m_once[256];

	bx::RingBufferControl m_ring;
	uint8_t m_char[256];
};

struct Gamepad
{
	Gamepad()
	{
		reset();
	}

	void reset()
	{
		memset(m_axis, 0, sizeof(m_axis) );
	}

	void setAxis(entry::GamepadAxis::Enum _axis, int32_t _value)
	{
		m_axis[_axis] = _value;
	}

	int32_t getAxis(entry::GamepadAxis::Enum _axis)
	{
		return m_axis[_axis];
	}

	int32_t m_axis[entry::GamepadAxis::Count];
};

struct Input
{
	Input()
	{
		reset();
	}

	~Input()
	{
	}

	void addBindings(const char* _name, const InputBinding* _bindings)
	{
		m_inputBindingsMap.insert(stl::make_pair(_name, _bindings) );
	}

	void removeBindings(const char* _name)
	{
		InputBindingMap::iterator it = m_inputBindingsMap.find(_name);
		if (it != m_inputBindingsMap.end() )
		{
			m_inputBindingsMap.erase(it);
		}
	}

	void process(const InputBinding* _bindings)
	{
		for (const InputBinding* binding = _bindings; binding->m_key != entry::Key::None; ++binding)
		{
			uint8_t modifiers;
			bool down =	Keyboard::decodeKeyState(m_keyboard.m_key[binding->m_key], modifiers);

			if (binding->m_flags == 1)
			{
				if (down)
				{
					if (modifiers == binding->m_modifiers
					&&  !m_keyboard.m_once[binding->m_key])
					{
						if (NULL == binding->m_fn)
						{
							cmdExec( (const char*)binding->m_userData);
						}
						else
						{
							binding->m_fn(binding->m_userData);
						}
						m_keyboard.m_once[binding->m_key] = true;
					}
				}
				else
				{
					m_keyboard.m_once[binding->m_key] = false;
				}
			}
			else
			{
				if (down
				&&  modifiers == binding->m_modifiers)
				{
					if (NULL == binding->m_fn)
					{
						cmdExec( (const char*)binding->m_userData);
					}
					else
					{
						binding->m_fn(binding->m_userData);
					}
				}
			}
		}
	}

	void process()
	{
		for (InputBindingMap::const_iterator it = m_inputBindingsMap.begin(); it != m_inputBindingsMap.end(); ++it)
		{
			process(it->second);
		}
	}

	void reset()
	{
		m_mouse.reset();
		m_keyboard.reset();
		for (uint32_t ii = 0; ii < BX_COUNTOF(m_gamepad); ++ii)
		{
			m_gamepad[ii].reset();
		}
	}

	typedef stl::unordered_map<const char*, const InputBinding*> InputBindingMap;
	InputBindingMap m_inputBindingsMap;
	Mouse m_mouse;
	Keyboard m_keyboard;
	Gamepad m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS];
};

static Input* s_input;

void inputInit()
{
	s_input = BX_NEW(entry::getAllocator(), Input);
}

void inputShutdown()
{
	BX_DELETE(entry::getAllocator(), s_input);
}

void inputAddBindings(const char* _name, const InputBinding* _bindings)
{
	s_input->addBindings(_name, _bindings);
}

void inputRemoveBindings(const char* _name)
{
	s_input->removeBindings(_name);
}

void inputProcess()
{
	s_input->process();
}

void inputSetMouseResolution(uint16_t _width, uint16_t _height)
{
	s_input->m_mouse.setResolution(_width, _height);
}

void inputSetKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
{
	s_input->m_keyboard.setKeyState(_key, _modifiers, _down);
}

bool inputGetKeyState(entry::Key::Enum _key, uint8_t* _modifiers)
{
	return s_input->m_keyboard.getKeyState(_key, _modifiers);
}

uint8_t inputGetModifiersState()
{
	return s_input->m_keyboard.getModifiersState();
}

void inputChar(uint8_t _len, const uint8_t _char[4])
{
	s_input->m_keyboard.pushChar(_len, _char);
}

const uint8_t* inputGetChar()
{
	return s_input->m_keyboard.popChar();
}

void inputCharFlush()
{
	s_input->m_keyboard.charFlush();
}

void inputSetMousePos(int32_t _mx, int32_t _my, int32_t _mz)
{
	s_input->m_mouse.setPos(_mx, _my, _mz);
}

void inputSetMouseButtonState(entry::MouseButton::Enum _button, uint8_t _state)
{
	s_input->m_mouse.setButtonState(_button, _state);
}

void inputGetMouse(float _mouse[3])
{
	_mouse[0] = s_input->m_mouse.m_norm[0];
	_mouse[1] = s_input->m_mouse.m_norm[1];
	_mouse[2] = s_input->m_mouse.m_norm[2];
	s_input->m_mouse.m_norm[0] = 0.0f;
	s_input->m_mouse.m_norm[1] = 0.0f;
	s_input->m_mouse.m_norm[2] = 0.0f;
}

bool inputIsMouseLocked()
{
	return s_input->m_mouse.m_lock;
}

void inputSetMouseLock(bool _lock)
{
	if (s_input->m_mouse.m_lock != _lock)
	{
		s_input->m_mouse.m_lock = _lock;
		entry::WindowHandle defaultWindow = { 0 };
		entry::setMouseLock(defaultWindow, _lock);
		if (_lock)
		{
			s_input->m_mouse.m_norm[0] = 0.0f;
			s_input->m_mouse.m_norm[1] = 0.0f;
			s_input->m_mouse.m_norm[2] = 0.0f;
		}
	}
}

void inputSetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis, int32_t _value)
{
	s_input->m_gamepad[_handle.idx].setAxis(_axis, _value);
}

int32_t inputGetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis)
{
	return s_input->m_gamepad[_handle.idx].getAxis(_axis);
}
<commit_msg>Using char* as key for unordered_map can lead to unexpected behavior (the hash used for the key is computed using pointer address, not string content)<commit_after>/*
 * Copyright 2010-2016 Branimir Karadzic. All rights reserved.
 * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
 */

#include <memory.h>

#include "entry_p.h"
#include "input.h"
#include "cmd.h"

#include <bx/allocator.h>
#include <bx/ringbuffer.h>
#include <tinystl/string.h>
#include <tinystl/allocator.h>
#include <tinystl/unordered_map.h>
namespace stl = tinystl;

struct Mouse
{
	Mouse()
		: m_width(1280)
		, m_height(720)
		, m_wheelDelta(120)
		, m_lock(false)
	{
	}

	void reset()
	{
		if (m_lock)
		{
			m_norm[0] = 0.0f;
			m_norm[1] = 0.0f;
			m_norm[2] = 0.0f;
		}

		memset(m_buttons, 0, sizeof(m_buttons) );
	}

	void setResolution(uint16_t _width, uint16_t _height)
	{
		m_width = _width;
		m_height = _height;
	}

	void setPos(int32_t _mx, int32_t _my, int32_t _mz)
	{
		m_absolute[0] = _mx;
		m_absolute[1] = _my;
		m_absolute[2] = _mz;
		m_norm[0] = float(_mx)/float(m_width);
		m_norm[1] = float(_my)/float(m_height);
		m_norm[2] = float(_mz)/float(m_wheelDelta);
	}

	void setButtonState(entry::MouseButton::Enum _button, uint8_t _state)
	{
		m_buttons[_button] = _state;
	}

	int32_t m_absolute[3];
	float m_norm[3];
	int32_t m_wheel;
	uint8_t m_buttons[entry::MouseButton::Count];
	uint16_t m_width;
	uint16_t m_height;
	uint16_t m_wheelDelta;
	bool m_lock;
};

struct Keyboard
{
	Keyboard()
		: m_ring(BX_COUNTOF(m_char) )
	{
	}

	void reset()
	{
		memset(m_key, 0, sizeof(m_key) );
		memset(m_once, 0xff, sizeof(m_once) );
	}

	static uint32_t encodeKeyState(uint8_t _modifiers, bool _down)
	{
		uint32_t state = 0;
		state |= uint32_t(_modifiers)<<16;
		state |= uint32_t(_down)<<8;
		return state;
	}

	static bool decodeKeyState(uint32_t _state, uint8_t& _modifiers)
	{
		_modifiers = (_state>>16)&0xff;
		return 0 != ( (_state>> 8)&0xff);
	}

	void setKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
	{
		m_key[_key] = encodeKeyState(_modifiers, _down);
		m_once[_key] = false;
	}

	bool getKeyState(entry::Key::Enum _key, uint8_t* _modifiers)
	{
		uint8_t modifiers;
		_modifiers = NULL == _modifiers ? &modifiers : _modifiers;

		return decodeKeyState(m_key[_key], *_modifiers);
	}

	uint8_t getModifiersState()
	{
		uint8_t modifiers = 0;
		for (uint32_t ii = 0; ii < entry::Key::Count; ++ii)
		{
			modifiers |= (m_key[ii]>>16)&0xff;
		}
		return modifiers;
	}

	void pushChar(uint8_t _len, const uint8_t _char[4])
	{
		for (uint32_t len = m_ring.reserve(4)
			; len < _len
			; len = m_ring.reserve(4)
			)
		{
			popChar();
		}

		memcpy(&m_char[m_ring.m_current], _char, 4);
		m_ring.commit(4);
	}

	const uint8_t* popChar()
	{
		if (0 < m_ring.available() )
		{
			uint8_t* utf8 = &m_char[m_ring.m_read];
			m_ring.consume(4);
			return utf8;
		}

		return NULL;
	}

	void charFlush()
	{
		m_ring.m_current = 0;
		m_ring.m_write   = 0;
		m_ring.m_read    = 0;
	}

	uint32_t m_key[256];
	bool m_once[256];

	bx::RingBufferControl m_ring;
	uint8_t m_char[256];
};

struct Gamepad
{
	Gamepad()
	{
		reset();
	}

	void reset()
	{
		memset(m_axis, 0, sizeof(m_axis) );
	}

	void setAxis(entry::GamepadAxis::Enum _axis, int32_t _value)
	{
		m_axis[_axis] = _value;
	}

	int32_t getAxis(entry::GamepadAxis::Enum _axis)
	{
		return m_axis[_axis];
	}

	int32_t m_axis[entry::GamepadAxis::Count];
};

struct Input
{
	Input()
	{
		reset();
	}

	~Input()
	{
	}

	void addBindings(const char* _name, const InputBinding* _bindings)
	{
		m_inputBindingsMap.insert(stl::make_pair(stl::string(_name), _bindings) );
	}

	void removeBindings(const char* _name)
	{
		InputBindingMap::iterator it = m_inputBindingsMap.find(stl::string(_name));
		if (it != m_inputBindingsMap.end() )
		{
			m_inputBindingsMap.erase(it);
		}
	}

	void process(const InputBinding* _bindings)
	{
		for (const InputBinding* binding = _bindings; binding->m_key != entry::Key::None; ++binding)
		{
			uint8_t modifiers;
			bool down =	Keyboard::decodeKeyState(m_keyboard.m_key[binding->m_key], modifiers);

			if (binding->m_flags == 1)
			{
				if (down)
				{
					if (modifiers == binding->m_modifiers
					&&  !m_keyboard.m_once[binding->m_key])
					{
						if (NULL == binding->m_fn)
						{
							cmdExec( (const char*)binding->m_userData);
						}
						else
						{
							binding->m_fn(binding->m_userData);
						}
						m_keyboard.m_once[binding->m_key] = true;
					}
				}
				else
				{
					m_keyboard.m_once[binding->m_key] = false;
				}
			}
			else
			{
				if (down
				&&  modifiers == binding->m_modifiers)
				{
					if (NULL == binding->m_fn)
					{
						cmdExec( (const char*)binding->m_userData);
					}
					else
					{
						binding->m_fn(binding->m_userData);
					}
				}
			}
		}
	}

	void process()
	{
		for (InputBindingMap::const_iterator it = m_inputBindingsMap.begin(); it != m_inputBindingsMap.end(); ++it)
		{
			process(it->second);
		}
	}

	void reset()
	{
		m_mouse.reset();
		m_keyboard.reset();
		for (uint32_t ii = 0; ii < BX_COUNTOF(m_gamepad); ++ii)
		{
			m_gamepad[ii].reset();
		}
	}

	typedef stl::unordered_map<stl::string, const InputBinding*> InputBindingMap;
	InputBindingMap m_inputBindingsMap;
	Mouse m_mouse;
	Keyboard m_keyboard;
	Gamepad m_gamepad[ENTRY_CONFIG_MAX_GAMEPADS];
};

static Input* s_input;

void inputInit()
{
	s_input = BX_NEW(entry::getAllocator(), Input);
}

void inputShutdown()
{
	BX_DELETE(entry::getAllocator(), s_input);
}

void inputAddBindings(const char* _name, const InputBinding* _bindings)
{
	s_input->addBindings(_name, _bindings);
}

void inputRemoveBindings(const char* _name)
{
	s_input->removeBindings(_name);
}

void inputProcess()
{
	s_input->process();
}

void inputSetMouseResolution(uint16_t _width, uint16_t _height)
{
	s_input->m_mouse.setResolution(_width, _height);
}

void inputSetKeyState(entry::Key::Enum _key, uint8_t _modifiers, bool _down)
{
	s_input->m_keyboard.setKeyState(_key, _modifiers, _down);
}

bool inputGetKeyState(entry::Key::Enum _key, uint8_t* _modifiers)
{
	return s_input->m_keyboard.getKeyState(_key, _modifiers);
}

uint8_t inputGetModifiersState()
{
	return s_input->m_keyboard.getModifiersState();
}

void inputChar(uint8_t _len, const uint8_t _char[4])
{
	s_input->m_keyboard.pushChar(_len, _char);
}

const uint8_t* inputGetChar()
{
	return s_input->m_keyboard.popChar();
}

void inputCharFlush()
{
	s_input->m_keyboard.charFlush();
}

void inputSetMousePos(int32_t _mx, int32_t _my, int32_t _mz)
{
	s_input->m_mouse.setPos(_mx, _my, _mz);
}

void inputSetMouseButtonState(entry::MouseButton::Enum _button, uint8_t _state)
{
	s_input->m_mouse.setButtonState(_button, _state);
}

void inputGetMouse(float _mouse[3])
{
	_mouse[0] = s_input->m_mouse.m_norm[0];
	_mouse[1] = s_input->m_mouse.m_norm[1];
	_mouse[2] = s_input->m_mouse.m_norm[2];
	s_input->m_mouse.m_norm[0] = 0.0f;
	s_input->m_mouse.m_norm[1] = 0.0f;
	s_input->m_mouse.m_norm[2] = 0.0f;
}

bool inputIsMouseLocked()
{
	return s_input->m_mouse.m_lock;
}

void inputSetMouseLock(bool _lock)
{
	if (s_input->m_mouse.m_lock != _lock)
	{
		s_input->m_mouse.m_lock = _lock;
		entry::WindowHandle defaultWindow = { 0 };
		entry::setMouseLock(defaultWindow, _lock);
		if (_lock)
		{
			s_input->m_mouse.m_norm[0] = 0.0f;
			s_input->m_mouse.m_norm[1] = 0.0f;
			s_input->m_mouse.m_norm[2] = 0.0f;
		}
	}
}

void inputSetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis, int32_t _value)
{
	s_input->m_gamepad[_handle.idx].setAxis(_axis, _value);
}

int32_t inputGetGamepadAxis(entry::GamepadHandle _handle, entry::GamepadAxis::Enum _axis)
{
	return s_input->m_gamepad[_handle.idx].getAxis(_axis);
}
<|endoftext|>


<commit_before>/*!
 * \file matrix_structure.inl
 * \brief In-Line subroutines of the matrix_structure.hpp file.
 * \author F. Palacios, A. Bueno, T. Economon
 * \version 6.2.0 "Falcon"
 *
 * The current SU2 release has been coordinated by the
 * SU2 International Developers Society <www.su2devsociety.org>
 * with selected contributions from the open-source community.
 *
 * The main research teams contributing to the current release are:
 *  - Prof. Juan J. Alonso's group at Stanford University.
 *  - Prof. Piero Colonna's group at Delft University of Technology.
 *  - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology.
 *  - Prof. Alberto Guardone's group at Polytechnic University of Milan.
 *  - Prof. Rafael Palacios' group at Imperial College London.
 *  - Prof. Vincent Terrapon's group at the University of Liege.
 *  - Prof. Edwin van der Weide's group at the University of Twente.
 *  - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics.
 *
 * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon,
 *                      Tim Albring, and the SU2 contributors.
 *
 * SU2 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.
 *
 * SU2 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 SU2. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

template<class ScalarType>
inline void CSysMatrix<ScalarType>::SetValZero(void) {
  if(NULL != matrix) {
	  for (unsigned long index = 0; index < nnz*nVar*nEqn; index++)
		matrix[index] = 0.0;
  }
}

template<class ScalarType>
template<class DstType, class SrcType>
inline DstType CSysMatrix<ScalarType>::ActiveAssign(const SrcType & val) const { return val; }

#ifdef CODI_REVERSE_TYPE
template<> template<>
inline passivedouble CSysMatrix<passivedouble>::ActiveAssign(const su2double & val) const { return SU2_TYPE::GetValue(val); }

template<> template<>
inline passivedouble CSysMatrix<su2double>::ActiveAssign(const su2double & val) const { return SU2_TYPE::GetValue(val); }
#endif

template<class ScalarType>
template<class DstType, class SrcType>
inline DstType CSysMatrix<ScalarType>::PassiveAssign(const SrcType & val) const {
#ifndef CODI_REVERSE_TYPE
  return val;
#else
  return SU2_TYPE::GetValue(val);
#endif
}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SetBlock(unsigned long block_i, unsigned long block_j, OtherType **val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] = PassiveAssign<ScalarType,OtherType>(val_block[iVar][jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SetBlock(unsigned long block_i, unsigned long block_j, OtherType *val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] = PassiveAssign<ScalarType,OtherType>(val_block[iVar*nVar+jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::AddBlock(unsigned long block_i, unsigned long block_j, OtherType **val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] += PassiveAssign<ScalarType,OtherType>(val_block[iVar][jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SubtractBlock(unsigned long block_i, unsigned long block_j, OtherType **val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] -= PassiveAssign<ScalarType,OtherType>(val_block[iVar][jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::AddVal2Diag(unsigned long block_i, OtherType val_matrix) {

  unsigned long step = 0, iVar, index;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_i) {	// Only elements on the diagonal
      for (iVar = 0; iVar < nVar; iVar++)
        matrix[(row_ptr[block_i]+step-1)*nVar*nVar+iVar*nVar+iVar] += PassiveAssign<ScalarType,OtherType>(val_matrix);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SetVal2Diag(unsigned long block_i, OtherType val_matrix) {

  unsigned long step = 0, iVar, jVar, index;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_i) {	// Only elements on the diagonal

      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nVar; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nVar+iVar*nVar+jVar] = 0.0;

      for (iVar = 0; iVar < nVar; iVar++)
        matrix[(row_ptr[block_i]+step-1)*nVar*nVar+iVar*nVar+iVar] = PassiveAssign<ScalarType,OtherType>(val_matrix);

      break;
    }
  }

}

template<class ScalarType>
inline CSysMatrixVectorProduct<ScalarType>::CSysMatrixVectorProduct(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CSysMatrixVectorProduct<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CSysMatrixVectorProduct::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->MatrixVectorProduct(u, v, geometry, config);
}

template<class ScalarType>
inline CSysMatrixVectorProductTransposed<ScalarType>::CSysMatrixVectorProductTransposed(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CSysMatrixVectorProductTransposed<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CSysMatrixVectorProduct::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->MatrixVectorProductTransposed(u, v, geometry, config);
}

template<class ScalarType>
inline CJacobiPreconditioner<ScalarType>::CJacobiPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CJacobiPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CJacobiPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeJacobiPreconditioner(u, v, geometry, config);
}

template<class ScalarType>
inline CILUPreconditioner<ScalarType>::CILUPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CILUPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CILUPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeILUPreconditioner(u, v, geometry, config);
}

template<class ScalarType>
inline CLU_SGSPreconditioner<ScalarType>::CLU_SGSPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
      geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CLU_SGSPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CLU_SGSPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeLU_SGSPreconditioner(u, v, geometry, config);
}

template<class ScalarType>
inline CLineletPreconditioner<ScalarType>::CLineletPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CLineletPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CLineletPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeLineletPreconditioner(u, v, geometry, config);
}
<commit_msg>forgot to handle directdiff in previous commit<commit_after>/*!
 * \file matrix_structure.inl
 * \brief In-Line subroutines of the matrix_structure.hpp file.
 * \author F. Palacios, A. Bueno, T. Economon
 * \version 6.2.0 "Falcon"
 *
 * The current SU2 release has been coordinated by the
 * SU2 International Developers Society <www.su2devsociety.org>
 * with selected contributions from the open-source community.
 *
 * The main research teams contributing to the current release are:
 *  - Prof. Juan J. Alonso's group at Stanford University.
 *  - Prof. Piero Colonna's group at Delft University of Technology.
 *  - Prof. Nicolas R. Gauger's group at Kaiserslautern University of Technology.
 *  - Prof. Alberto Guardone's group at Polytechnic University of Milan.
 *  - Prof. Rafael Palacios' group at Imperial College London.
 *  - Prof. Vincent Terrapon's group at the University of Liege.
 *  - Prof. Edwin van der Weide's group at the University of Twente.
 *  - Lab. of New Concepts in Aeronautics at Tech. Institute of Aeronautics.
 *
 * Copyright 2012-2019, Francisco D. Palacios, Thomas D. Economon,
 *                      Tim Albring, and the SU2 contributors.
 *
 * SU2 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.
 *
 * SU2 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 SU2. If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

template<class ScalarType>
inline void CSysMatrix<ScalarType>::SetValZero(void) {
  if(NULL != matrix) {
	  for (unsigned long index = 0; index < nnz*nVar*nEqn; index++)
		matrix[index] = 0.0;
  }
}

template<class ScalarType>
template<class DstType, class SrcType>
inline DstType CSysMatrix<ScalarType>::ActiveAssign(const SrcType & val) const { return val; }

#ifdef CODI_REVERSE_TYPE
template<> template<>
inline passivedouble CSysMatrix<passivedouble>::ActiveAssign(const su2double & val) const { return SU2_TYPE::GetValue(val); }

template<> template<>
inline passivedouble CSysMatrix<su2double>::ActiveAssign(const su2double & val) const { return SU2_TYPE::GetValue(val); }
#endif

template<class ScalarType>
template<class DstType, class SrcType>
inline DstType CSysMatrix<ScalarType>::PassiveAssign(const SrcType & val) const {
#if defined(CODI_REVERSE_TYPE) || defined(CODI_FORWARD_TYPE)
  return SU2_TYPE::GetValue(val);
#else
  return val;
#endif
}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SetBlock(unsigned long block_i, unsigned long block_j, OtherType **val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] = PassiveAssign<ScalarType,OtherType>(val_block[iVar][jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SetBlock(unsigned long block_i, unsigned long block_j, OtherType *val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] = PassiveAssign<ScalarType,OtherType>(val_block[iVar*nVar+jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::AddBlock(unsigned long block_i, unsigned long block_j, OtherType **val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] += PassiveAssign<ScalarType,OtherType>(val_block[iVar][jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SubtractBlock(unsigned long block_i, unsigned long block_j, OtherType **val_block) {

  unsigned long iVar, jVar, index, step = 0;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_j) {
      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nEqn; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nEqn+iVar*nEqn+jVar] -= PassiveAssign<ScalarType,OtherType>(val_block[iVar][jVar]);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::AddVal2Diag(unsigned long block_i, OtherType val_matrix) {

  unsigned long step = 0, iVar, index;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_i) {	// Only elements on the diagonal
      for (iVar = 0; iVar < nVar; iVar++)
        matrix[(row_ptr[block_i]+step-1)*nVar*nVar+iVar*nVar+iVar] += PassiveAssign<ScalarType,OtherType>(val_matrix);
      break;
    }
  }

}

template<class ScalarType>
template<class OtherType>
inline void CSysMatrix<ScalarType>::SetVal2Diag(unsigned long block_i, OtherType val_matrix) {

  unsigned long step = 0, iVar, jVar, index;

  for (index = row_ptr[block_i]; index < row_ptr[block_i+1]; index++) {
    step++;
    if (col_ind[index] == block_i) {	// Only elements on the diagonal

      for (iVar = 0; iVar < nVar; iVar++)
        for (jVar = 0; jVar < nVar; jVar++)
          matrix[(row_ptr[block_i]+step-1)*nVar*nVar+iVar*nVar+jVar] = 0.0;

      for (iVar = 0; iVar < nVar; iVar++)
        matrix[(row_ptr[block_i]+step-1)*nVar*nVar+iVar*nVar+iVar] = PassiveAssign<ScalarType,OtherType>(val_matrix);

      break;
    }
  }

}

template<class ScalarType>
inline CSysMatrixVectorProduct<ScalarType>::CSysMatrixVectorProduct(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CSysMatrixVectorProduct<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CSysMatrixVectorProduct::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->MatrixVectorProduct(u, v, geometry, config);
}

template<class ScalarType>
inline CSysMatrixVectorProductTransposed<ScalarType>::CSysMatrixVectorProductTransposed(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CSysMatrixVectorProductTransposed<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CSysMatrixVectorProduct::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->MatrixVectorProductTransposed(u, v, geometry, config);
}

template<class ScalarType>
inline CJacobiPreconditioner<ScalarType>::CJacobiPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CJacobiPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CJacobiPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeJacobiPreconditioner(u, v, geometry, config);
}

template<class ScalarType>
inline CILUPreconditioner<ScalarType>::CILUPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CILUPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CILUPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeILUPreconditioner(u, v, geometry, config);
}

template<class ScalarType>
inline CLU_SGSPreconditioner<ScalarType>::CLU_SGSPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
      geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CLU_SGSPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CLU_SGSPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeLU_SGSPreconditioner(u, v, geometry, config);
}

template<class ScalarType>
inline CLineletPreconditioner<ScalarType>::CLineletPreconditioner(CSysMatrix<ScalarType> & matrix_ref, CGeometry *geometry_ref, CConfig *config_ref) {
  sparse_matrix = &matrix_ref;
  geometry = geometry_ref;
  config = config_ref;
}

template<class ScalarType>
inline void CLineletPreconditioner<ScalarType>::operator()(const CSysVector<ScalarType> & u, CSysVector<ScalarType> & v) const {
  if (sparse_matrix == NULL) {
    cerr << "CLineletPreconditioner::operator()(const CSysVector &, CSysVector &): " << endl;
    cerr << "pointer to sparse matrix is NULL." << endl;
    throw(-1);
  }
  sparse_matrix->ComputeLineletPreconditioner(u, v, geometry, config);
}
<|endoftext|>


<commit_before>#include "Comparison.h"
#include "Utils.h"
#include <cmath>

namespace ColorSpace {
	double EuclideanComparison::Compare(IColorSpace *a, IColorSpace *b) {
		Rgb rgb_a;
		Rgb rgb_b;

		a->ToRgb(&rgb_a);
		b->ToRgb(&rgb_b);

		return sqrt(SQR(rgb_a.r - rgb_b.r) + SQR(rgb_a.g - rgb_b.g) + SQR(rgb_a.b - rgb_a.b));
	}

	double Cie1976Comparison::Compare(IColorSpace *a, IColorSpace *b) {
		Lab lab_a;
		Lab lab_b;

		a->To<Lab>(&lab_a);
		b->To<Lab>(&lab_b);

		return sqrt(SQR(lab_a.l - lab_b.l) + SQR(lab_a.a - lab_b.a) + SQR(lab_a.b - lab_b.b));
	}

	Cie94Comparison::Application::Application(Cie94Comparison::APPLICATION appType) {
		switch (appType) {
		case GRAPHIC_ARTS:
			kl = 1.0;
			k1 = 0.045;
			k2 = 0.015;
			break;
		case TEXTILES:
			kl = 2.0;
			k1 = 0.048;
			k2 = 0.014;
			break;
		}
	}

	double Cie94Comparison::Compare(IColorSpace *a, IColorSpace *b, APPLICATION appType) {
		Application app(appType);
		Lab lab_a;
		Lab lab_b;

		a->To<Lab>(&lab_a);
		b->To<Lab>(&lab_b);

		double deltaL = lab_a.l - lab_b.l;
		double deltaA = lab_a.a - lab_b.a;
		double deltaB = lab_a.b - lab_b.b;

		double c1 = sqrt(SQR(lab_a.a) + SQR(lab_a.b));
		double c2 = sqrt(SQR(lab_b.a) + SQR(lab_b.b));
		double deltaC = c1 - c2;

		double deltaH = SQR(deltaA) + SQR(deltaB) - SQR(deltaC);

		double sl = 1.0;
		double sc = 1.0 + app.k1*c1;
		double sh = 1.0 + app.k2*c1;

		deltaL /= app.kl*sl;
		deltaC /= sc;

		return sqrt(SQR(deltaL) + SQR(deltaC) + deltaH/SQR(sh));
	}

	double Cie2000Comparison::Compare(IColorSpace *a, IColorSpace *b) {
		const double eps = 1e-5;
		Lab lab_a;
		Lab lab_b;

		a->To<Lab>(&lab_a);
		b->To<Lab>(&lab_b);

		// calculate ci, hi, i=1,2
		double c1 = sqrt(SQR(lab_a.a) + SQR(lab_a.b));
		double c2 = sqrt(SQR(lab_b.a) + SQR(lab_b.b));
		double meanC = (c1 + c2) / 2.0;
		double meanC7 = POW7(meanC);

		double g = 0.5*(1 - sqrt(meanC7 / (meanC7 + 6103515625.))); // 0.5*(1-sqrt(meanC^7/(meanC^7+25^7)))
		double a1p = lab_a.a * (1 + g);
		double a2p = lab_b.a * (1 + g);

		c1 = sqrt(SQR(a1p) + SQR(lab_a.b));
		c2 = sqrt(SQR(a2p) + SQR(lab_b.b));
		double h1 = fmod(atan2(lab_a.b, a1p) + 2*M_PI, 2*M_PI);
		double h2 = fmod(atan2(lab_b.b, a2p) + 2*M_PI, 2*M_PI);

		// compute deltaL, deltaC, deltaH
		double deltaL = lab_b.l - lab_a.l;
		double deltaC = c2 - c1;
		double deltah;

		if (c1*c2 < eps) {
			deltah = 0;
		}
		if (std::abs(h2 - h1) <= M_PI) {
			deltah = h2 - h1;
		}
		else if (h2 > h1) {
			deltah = h2 - h1 - 2* M_PI;
		}
		else {
			deltah = h2 - h1 + 2 * M_PI;
		}

		double deltaH = 2 * sqrt(c1*c2)*sin(deltah / 2);

		// calculate CIEDE2000
		double meanL = (lab_a.l + lab_b.l) / 2;
		meanC = (c1 + c2) / 2.0;
		meanC7 = POW7(meanC);
		double meanH;

		if (c1*c2 < eps) {
			meanH = h1 + h2;
		}
		if (std::abs(h1 - h2) <= M_PI + eps) {
			meanH = (h1 + h2) / 2;
		}
		else if (h1 + h2 < 2*M_PI) {
			meanH = (h1 + h2 + 2*M_PI) / 2;
		}
		else {
			meanH = (h1 + h2 - 2*M_PI) / 2;
		}

		double T = 1
			- 0.17*cos(meanH - DegToRad(30))
			+ 0.24*cos(2 * meanH)
			+ 0.32*cos(3 * meanH + DegToRad(6))
			- 0.2*cos(4 * meanH - DegToRad(63));
		double sl = 1 + (0.015*SQR(meanL - 50)) / sqrt(20 + SQR(meanL - 50));
		double sc = 1 + 0.045*meanC;
		double sh = 1 + 0.015*meanC*T;
		double rc = 2 * sqrt(meanC7 / (meanC7 + 6103515625.));
		double rt = -sin(DegToRad(60 * exp(-SQR((RadToDeg(meanH) - 275) / 25)))) * rc;

		return sqrt(SQR(deltaL / sl) + SQR(deltaC / sc) + SQR(deltaH / sh) + rt * deltaC / sc * deltaH / sh);
	}

	const double CmcComparison::defaultLightness = 2.;
	const double CmcComparison::defaultChroma = 1.;
	double CmcComparison::Compare(IColorSpace *a, IColorSpace *b) {
		Lch lch_a;
		Lch lch_b;

		a->To<Lch>(&lch_a);
		b->To<Lch>(&lch_b);

		double deltaL = lch_a.l - lch_b.l;
		double deltaC = lch_a.c - lch_b.c;
		double deltaH = 0;

		double f = sqrt(POW4(lch_a.c) / (POW4(lch_a.c) + 1900));
		double t = (164 <= lch_a.h && lch_a.h <= 345) ? (0.56 + std::abs(0.2*cos(lch_a.h + 168))) : (0.36 + abs(0.4*cos(lch_a.h + 35)));

		double sl = (lch_a.l < 16) ? 0.511 : (0.040975*lch_a.l / (1 + 0.01765*lch_a.l));
		double sc = 0.0638*lch_a.c / (1 + 0.0131*lch_a.c) + 0.638;
		double sh = sc*(f*t + 1 - f);

		return sqrt(SQR(deltaL / (defaultLightness*sl)) + SQR(deltaC / (defaultChroma*sc)) + SQR(deltaH / sh));
	}
}

<commit_msg>Fix bug in EuclideanComparison<commit_after>#include "Comparison.h"
#include "Utils.h"
#include <cmath>

namespace ColorSpace {
	double EuclideanComparison::Compare(IColorSpace *a, IColorSpace *b) {
		Rgb rgb_a;
		Rgb rgb_b;

		a->ToRgb(&rgb_a);
		b->ToRgb(&rgb_b);

		return sqrt(SQR(rgb_a.r - rgb_b.r) + SQR(rgb_a.g - rgb_b.g) + SQR(rgb_a.b - rgb_b.b));
	}

	double Cie1976Comparison::Compare(IColorSpace *a, IColorSpace *b) {
		Lab lab_a;
		Lab lab_b;

		a->To<Lab>(&lab_a);
		b->To<Lab>(&lab_b);

		return sqrt(SQR(lab_a.l - lab_b.l) + SQR(lab_a.a - lab_b.a) + SQR(lab_a.b - lab_b.b));
	}

	Cie94Comparison::Application::Application(Cie94Comparison::APPLICATION appType) {
		switch (appType) {
		case GRAPHIC_ARTS:
			kl = 1.0;
			k1 = 0.045;
			k2 = 0.015;
			break;
		case TEXTILES:
			kl = 2.0;
			k1 = 0.048;
			k2 = 0.014;
			break;
		}
	}

	double Cie94Comparison::Compare(IColorSpace *a, IColorSpace *b, APPLICATION appType) {
		Application app(appType);
		Lab lab_a;
		Lab lab_b;

		a->To<Lab>(&lab_a);
		b->To<Lab>(&lab_b);

		double deltaL = lab_a.l - lab_b.l;
		double deltaA = lab_a.a - lab_b.a;
		double deltaB = lab_a.b - lab_b.b;

		double c1 = sqrt(SQR(lab_a.a) + SQR(lab_a.b));
		double c2 = sqrt(SQR(lab_b.a) + SQR(lab_b.b));
		double deltaC = c1 - c2;

		double deltaH = SQR(deltaA) + SQR(deltaB) - SQR(deltaC);

		double sl = 1.0;
		double sc = 1.0 + app.k1*c1;
		double sh = 1.0 + app.k2*c1;

		deltaL /= app.kl*sl;
		deltaC /= sc;

		return sqrt(SQR(deltaL) + SQR(deltaC) + deltaH/SQR(sh));
	}

	double Cie2000Comparison::Compare(IColorSpace *a, IColorSpace *b) {
		const double eps = 1e-5;
		Lab lab_a;
		Lab lab_b;

		a->To<Lab>(&lab_a);
		b->To<Lab>(&lab_b);

		// calculate ci, hi, i=1,2
		double c1 = sqrt(SQR(lab_a.a) + SQR(lab_a.b));
		double c2 = sqrt(SQR(lab_b.a) + SQR(lab_b.b));
		double meanC = (c1 + c2) / 2.0;
		double meanC7 = POW7(meanC);

		double g = 0.5*(1 - sqrt(meanC7 / (meanC7 + 6103515625.))); // 0.5*(1-sqrt(meanC^7/(meanC^7+25^7)))
		double a1p = lab_a.a * (1 + g);
		double a2p = lab_b.a * (1 + g);

		c1 = sqrt(SQR(a1p) + SQR(lab_a.b));
		c2 = sqrt(SQR(a2p) + SQR(lab_b.b));
		double h1 = fmod(atan2(lab_a.b, a1p) + 2*M_PI, 2*M_PI);
		double h2 = fmod(atan2(lab_b.b, a2p) + 2*M_PI, 2*M_PI);

		// compute deltaL, deltaC, deltaH
		double deltaL = lab_b.l - lab_a.l;
		double deltaC = c2 - c1;
		double deltah;

		if (c1*c2 < eps) {
			deltah = 0;
		}
		if (std::abs(h2 - h1) <= M_PI) {
			deltah = h2 - h1;
		}
		else if (h2 > h1) {
			deltah = h2 - h1 - 2* M_PI;
		}
		else {
			deltah = h2 - h1 + 2 * M_PI;
		}

		double deltaH = 2 * sqrt(c1*c2)*sin(deltah / 2);

		// calculate CIEDE2000
		double meanL = (lab_a.l + lab_b.l) / 2;
		meanC = (c1 + c2) / 2.0;
		meanC7 = POW7(meanC);
		double meanH;

		if (c1*c2 < eps) {
			meanH = h1 + h2;
		}
		if (std::abs(h1 - h2) <= M_PI + eps) {
			meanH = (h1 + h2) / 2;
		}
		else if (h1 + h2 < 2*M_PI) {
			meanH = (h1 + h2 + 2*M_PI) / 2;
		}
		else {
			meanH = (h1 + h2 - 2*M_PI) / 2;
		}

		double T = 1
			- 0.17*cos(meanH - DegToRad(30))
			+ 0.24*cos(2 * meanH)
			+ 0.32*cos(3 * meanH + DegToRad(6))
			- 0.2*cos(4 * meanH - DegToRad(63));
		double sl = 1 + (0.015*SQR(meanL - 50)) / sqrt(20 + SQR(meanL - 50));
		double sc = 1 + 0.045*meanC;
		double sh = 1 + 0.015*meanC*T;
		double rc = 2 * sqrt(meanC7 / (meanC7 + 6103515625.));
		double rt = -sin(DegToRad(60 * exp(-SQR((RadToDeg(meanH) - 275) / 25)))) * rc;

		return sqrt(SQR(deltaL / sl) + SQR(deltaC / sc) + SQR(deltaH / sh) + rt * deltaC / sc * deltaH / sh);
	}

	const double CmcComparison::defaultLightness = 2.;
	const double CmcComparison::defaultChroma = 1.;
	double CmcComparison::Compare(IColorSpace *a, IColorSpace *b) {
		Lch lch_a;
		Lch lch_b;

		a->To<Lch>(&lch_a);
		b->To<Lch>(&lch_b);

		double deltaL = lch_a.l - lch_b.l;
		double deltaC = lch_a.c - lch_b.c;
		double deltaH = 0;

		double f = sqrt(POW4(lch_a.c) / (POW4(lch_a.c) + 1900));
		double t = (164 <= lch_a.h && lch_a.h <= 345) ? (0.56 + std::abs(0.2*cos(lch_a.h + 168))) : (0.36 + abs(0.4*cos(lch_a.h + 35)));

		double sl = (lch_a.l < 16) ? 0.511 : (0.040975*lch_a.l / (1 + 0.01765*lch_a.l));
		double sc = 0.0638*lch_a.c / (1 + 0.0131*lch_a.c) + 0.638;
		double sh = sc*(f*t + 1 - f);

		return sqrt(SQR(deltaL / (defaultLightness*sl)) + SQR(deltaC / (defaultChroma*sc)) + SQR(deltaH / sh));
	}
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log$
Revision 1.5  2007/11/23 19:28:52  alla
bug fixed

Version 2.1  2007/11/21
Preprocessor storing data to OCDB (T.Malkiewicz)

Version 1.1  2006/10
Preliminary test version (T.Malkiewicz)
*/

// T0 preprocessor:
// 1) takes data from DCS and passes it to the class AliTOFDataDCS for processing and writes the result to the Reference DB.
// 2) takes data form DAQ (both from Laser Calibration and Physics runs), processes it, and stores either to OCDB or to Reference DB.

#include "AliT0Preprocessor.h"
#include "AliT0DataDCS.h"
#include "AliT0CalibWalk.h"
#include "AliT0CalibTimeEq.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"

#include <TTimeStamp.h>
#include <TFile.h>
#include <TObjString.h>
#include <TNamed.h>
#include "AliT0Dqclass.h"

ClassImp(AliT0Preprocessor)

//____________________________________________________
AliT0Preprocessor::AliT0Preprocessor(AliShuttleInterface* shuttle) : AliPreprocessor("T00", shuttle), fData(0)
{
  //constructor
}
//____________________________________________________

AliT0Preprocessor::~AliT0Preprocessor()
{
  delete fData;
  fData = 0;
}
//____________________________________________________

void AliT0Preprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
{
  AliPreprocessor::Initialize(run, startTime, endTime);
  AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run, TTimeStamp(startTime).AsString(), TTimeStamp(endTime).AsString()));
  fData = new AliT0DataDCS(fRun, fStartTime, fEndTime);
}
//____________________________________________________

UInt_t AliT0Preprocessor::Process(TMap* dcsAliasMap )
{
  // T0 preprocessor return codes:
  // return=0 : all ok
  // return=1 : no DCS input data
  // return=2 : failed to store DCS data
  // return=3 : no Laser data (Walk correction)
  // return=4 : failed to store OCDB time equalized data
  // return=5 : no DAQ input for OCDB
  // return=6 : failed to retrieve DAQ data from OCDB
  // return=7 : failed to store T0 OCDB data

	Bool_t resultDCSMap=kFALSE;
	Bool_t resultDCSStore=kFALSE;
	Bool_t resultLaser=kFALSE;
	Bool_t resultOnline=kFALSE;

        if(!dcsAliasMap)
        {
          Log("No DCS input data");
          return 1;
        }
        else
        {
	  /*
          resultDCSMap=fData->ProcessData(*dcsAliasMap);
          if(!resultDCSMap)
          {
            Log("Error when processing DCS data");
            return 2;// return error Code for processed DCS data not stored
          }
          else
          {
	    Float_t *meanScaler[24] = fData->GetScalerMean();

            AliCDBMetaData metaDataDCS;
            metaDataDCS.SetBeamPeriod(0);
            metaDataDCS.SetResponsible("Tomasz Malkiewicz");
            metaDataDCS.SetComment("This preprocessor fills an AliTODataDCS object.");
            AliInfo("Storing DCS Data");
            resultDCSStore = Store("Calib","DCSData",meanScaler, &metaDataDCS);
            if (!resultDCSStore)
            {
              Log("Some problems occurred while storing DCS data results in ReferenceDB");
              return 2;// return error Code for processed DCS data not stored
            }

          }
	  */
        }

        // processing DAQ

        TString runType = GetRunType();

        if(runType == "T0_STANDALONE_LASER")
        {
          TList* list = GetFileSources(kDAQ, "LASER");
          if (list)
          {
            TIter iter(list);
            TObjString *source;
            while ((source = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *laserFile = GetFile(kDAQ, "LASER", source->GetName());
              if (laserFile)
              {
                Log(Form("File with Id LASER found in source %s!", source->GetName()));
                AliT0CalibWalk *laser = new AliT0CalibWalk();
                laser->MakeWalkCorrGraph(laserFile);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Walk correction from laser runs.");
		//TObjArray* arrLaser = laser->GetfWalk();
		resultLaser=Store("Calib","Slewing_Walk", laser, &metaData, 0, 1);
                delete laser;
              }
              else
              {
                Log(Form("Could not find file with Id LASER in source %s!", source->GetName()));
                return 1;
              }
            }
            if (!resultLaser)
            {
              Log("No Laser Data stored");
              return 3;//return error code for failure in storing Laser Data
            }
          }
        }
        else if(runType == "PHYSICS")
        {
          TList* listPhys = GetFileSources(kDAQ, "PHYSICS");
          if (listPhys)
          {
            TIter iter(listPhys);
            TObjString *sourcePhys;
            while ((sourcePhys = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *filePhys = GetFile(kDAQ, "PHYSICS", sourcePhys->GetName());
              if (filePhys)
              {
                AliT0CalibTimeEq *online = new AliT0CalibTimeEq();
                online->Reset();
                online->ComputeOnlineParams("CFD", 20, 4., filePhys);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Time equalizing result.");
                resultOnline = Store("Calib","TimeDelay", online, &metaData, 0, 1);
                delete online;
              }
              else
              {
                Log(Form("Could not find file with Id PHYSICS in source %s!", sourcePhys->GetName()));
                return 1;
              }
            }
            if (!resultOnline)
            {
              Log("No Laser Data stored");
              return 4;//return error code for failure in storing OCDB Data
            }
          }
        }

  return 0;
}

<commit_msg>bug fixed by Alberto<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log$
Revision 1.7  2007/12/06 16:35:24  alla
new bugs fixed by Tomek

Revision 1.5  2007/11/23 19:28:52  alla
bug fixed

Version 2.1  2007/11/21
Preprocessor storing data to OCDB (T.Malkiewicz)

Version 1.1  2006/10
Preliminary test version (T.Malkiewicz)
*/

// T0 preprocessor:
// 1) takes data from DCS and passes it to the class AliTOFDataDCS for processing and writes the result to the Reference DB.
// 2) takes data form DAQ (both from Laser Calibration and Physics runs), processes it, and stores either to OCDB or to Reference DB.

#include "AliT0Preprocessor.h"
#include "AliT0DataDCS.h"
#include "AliT0CalibWalk.h"
#include "AliT0CalibTimeEq.h"

#include "AliCDBMetaData.h"
#include "AliDCSValue.h"
#include "AliLog.h"

#include <TTimeStamp.h>
#include <TFile.h>
#include <TObjString.h>
#include <TNamed.h>
#include "AliT0Dqclass.h"

ClassImp(AliT0Preprocessor)

//____________________________________________________
AliT0Preprocessor::AliT0Preprocessor(AliShuttleInterface* shuttle) : AliPreprocessor("T00", shuttle), fData(0)
{
  //constructor
}
//____________________________________________________

AliT0Preprocessor::~AliT0Preprocessor()
{
  delete fData;
  fData = 0;
}
//____________________________________________________

void AliT0Preprocessor::Initialize(Int_t run, UInt_t startTime, UInt_t endTime)
{
  AliPreprocessor::Initialize(run, startTime, endTime);
  AliInfo(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run, TTimeStamp(startTime).AsString(), TTimeStamp(endTime).AsString()));
  fData = new AliT0DataDCS(fRun, fStartTime, fEndTime);
}
//____________________________________________________

UInt_t AliT0Preprocessor::Process(TMap* dcsAliasMap )
{
  // T0 preprocessor return codes:
  // return=0 : all ok
  // return=1 : no DCS input data
  // return=2 : failed to store DCS data
  // return=3 : no Laser data (Walk correction)
  // return=4 : failed to store OCDB time equalized data
  // return=5 : no DAQ input for OCDB
  // return=6 : failed to retrieve DAQ data from OCDB
  // return=7 : failed to store T0 OCDB data

	Bool_t resultDCSMap=kFALSE;
	Bool_t resultDCSStore=kFALSE;
	Bool_t resultLaser=kFALSE;
	Bool_t resultOnline=kFALSE;

        if(!dcsAliasMap)
        {
          Log("No DCS input data");
          return 1;
        }
        else
        {
	  /*
          resultDCSMap=fData->ProcessData(*dcsAliasMap);
          if(!resultDCSMap)
          {
            Log("Error when processing DCS data");
            return 2;// return error Code for processed DCS data not stored
          }
          else
          {
	    Float_t *meanScaler[24] = fData->GetScalerMean();

            AliCDBMetaData metaDataDCS;
            metaDataDCS.SetBeamPeriod(0);
            metaDataDCS.SetResponsible("Tomasz Malkiewicz");
            metaDataDCS.SetComment("This preprocessor fills an AliTODataDCS object.");
            AliInfo("Storing DCS Data");
            resultDCSStore = Store("Calib","DCSData",meanScaler, &metaDataDCS);
            if (!resultDCSStore)
            {
              Log("Some problems occurred while storing DCS data results in ReferenceDB");
              return 2;// return error Code for processed DCS data not stored
            }

          }
	  */
        }

        // processing DAQ

        TString runType = GetRunType();

        if(runType == "T0_STANDALONE_LASER")
        {
          TList* list = GetFileSources(kDAQ, "LASER");
          if (list)
          {
            TIter iter(list);
            TObjString *source;
            while ((source = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *laserFile = GetFile(kDAQ, "LASER", source->GetName());
              if (laserFile)
              {
                Log(Form("File with Id LASER found in source %s!", source->GetName()));
                AliT0CalibWalk *laser = new AliT0CalibWalk();
                laser->MakeWalkCorrGraph(laserFile);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Walk correction from laser runs.");
		//TObjArray* arrLaser = laser->GetfWalk();
		resultLaser=Store("Calib","Slewing_Walk", laser, &metaData, 0, 1);
                delete laser;
              }
              else
              {
                Log(Form("Could not find file with Id LASER in source %s!", source->GetName()));
                return 1;
              }
            }
            if (!resultLaser)
            {
              Log("No Laser Data stored");
              return 3;//return error code for failure in storing Laser Data
            }
          } else {
	  	Log("No sources found for id LASER!");
		return 1;
	  }
        }
        else if(runType == "PHYSICS")
        {
          TList* listPhys = GetFileSources(kDAQ, "PHYSICS");
          if (listPhys)
          {
            TIter iter(listPhys);
            TObjString *sourcePhys;
            while ((sourcePhys = dynamic_cast<TObjString *> (iter.Next())))
            {
              const char *filePhys = GetFile(kDAQ, "PHYSICS", sourcePhys->GetName());
              if (filePhys)
              {
                AliT0CalibTimeEq *online = new AliT0CalibTimeEq();
                online->Reset();
                online->ComputeOnlineParams("CFD", 20, 4., filePhys);
                AliCDBMetaData metaData;
                metaData.SetBeamPeriod(0);
                metaData.SetResponsible("Tomek&Michal");
                metaData.SetComment("Time equalizing result.");
                resultOnline = Store("Calib","TimeDelay", online, &metaData, 0, 1);
                delete online;
              }
              else
              {
                Log(Form("Could not find file with Id PHYSICS in source %s!", sourcePhys->GetName()));
                return 1;
              }
            }
            if (!resultOnline)
            {
              Log("No Laser Data stored");
              return 4;//return error code for failure in storing OCDB Data
            }
          } else {
	  	Log("No sources found for id PHYSICS!");
		return 1;
	  }
        }

  return 0;
}

<|endoftext|>


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

#pragma once

#include <thrust/iterator/zip_iterator.h>
#include <thrust/detail/tuple_transform.h>

namespace thrust
{

template <typename IteratorTuple>
  zip_iterator<IteratorTuple>
    ::zip_iterator(void)
{
} // end zip_iterator::zip_iterator()

template <typename IteratorTuple>
  zip_iterator<IteratorTuple>
    ::zip_iterator(IteratorTuple iterator_tuple)
      :m_iterator_tuple(iterator_tuple)
{
} // end zip_iterator::zip_iterator()

template <typename IteratorTuple>
  template <typename OtherIteratorTuple>
    zip_iterator<IteratorTuple>
      ::zip_iterator(const zip_iterator<OtherIteratorTuple> &other,
                     typename thrust::detail::enable_if_convertible<
                       OtherIteratorTuple,
                       IteratorTuple
                     >::type *)
        :m_iterator_tuple(other.get_iterator_tuple())
{
} // end zip_iterator::zip_iterator()

template <typename IteratorTuple>
const IteratorTuple &zip_iterator<IteratorTuple>
  ::get_iterator_tuple(void) const
{
  return m_iterator_tuple;
} // end zip_iterator::get_iterator_tuple()

template <typename IteratorTuple>
  typename zip_iterator<IteratorTuple>::super_t::reference
    zip_iterator<IteratorTuple>
      ::dereference(void) const
{
  using namespace detail::tuple_impl_specific;

  return thrust::detail::tuple_host_device_transform<detail::dereference_iterator::template apply>(get_iterator_tuple(), detail::dereference_iterator());
} // end zip_iterator::dereference()

template <typename IteratorTuple>
  template <typename OtherIteratorTuple>
    bool zip_iterator<IteratorTuple>
      ::equal(const zip_iterator<OtherIteratorTuple> &other) const
{
  return get<0>(get_iterator_tuple()) == get<0>(other.get_iterator_tuple());
} // end zip_iterator::equal()

template <typename IteratorTuple>
  void zip_iterator<IteratorTuple>
    ::advance(typename super_t::difference_type n)
{
  using namespace detail::tuple_impl_specific;

  // XXX note that we use a pointer to System to dispatch to avoid
  //     default construction of a System
  typename thrust::iterator_system<zip_iterator>::type *use_me_to_dispatch = 0;

  // dispatch on system
  tuple_for_each(m_iterator_tuple,
                 detail::advance_iterator<typename super_t::difference_type>(n),
                 use_me_to_dispatch);
} // end zip_iterator::advance()

template <typename IteratorTuple>
  void zip_iterator<IteratorTuple>
    ::increment(void)
{
  using namespace detail::tuple_impl_specific;

  // XXX note that we use a pointer to System to dispatch to avoid
  //     default construction of a System
  typename thrust::iterator_system<zip_iterator>::type *use_me_to_dispatch = 0;

  // dispatch on system
  tuple_for_each(m_iterator_tuple, detail::increment_iterator(),
                 use_me_to_dispatch);
} // end zip_iterator::increment()

template <typename IteratorTuple>
  void zip_iterator<IteratorTuple>
    ::decrement(void)
{
  using namespace detail::tuple_impl_specific;

  // dispatch on system
  tuple_for_each(m_iterator_tuple, detail::decrement_iterator(),
                 typename thrust::iterator_system<zip_iterator>::type());
} // end zip_iterator::decrement()

template <typename IteratorTuple>
  template <typename OtherIteratorTuple>
    typename zip_iterator<IteratorTuple>::super_t::difference_type
      zip_iterator<IteratorTuple>
        ::distance_to(const zip_iterator<OtherIteratorTuple> &other) const
{
  return get<0>(other.get_iterator_tuple()) - get<0>(get_iterator_tuple());
} // end zip_iterator::distance_to()

template <typename IteratorTuple>
  zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t)
{
  return zip_iterator<IteratorTuple>(t);
} // end make_zip_iterator()

} // end thrust

<commit_msg>Port zip_iterator::decrement to the pointer-based path for tuple_for_each.<commit_after>/*
 *  Copyright 2008-2012 NVIDIA Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#pragma once

#include <thrust/iterator/zip_iterator.h>
#include <thrust/detail/tuple_transform.h>

namespace thrust
{

template <typename IteratorTuple>
  zip_iterator<IteratorTuple>
    ::zip_iterator(void)
{
} // end zip_iterator::zip_iterator()

template <typename IteratorTuple>
  zip_iterator<IteratorTuple>
    ::zip_iterator(IteratorTuple iterator_tuple)
      :m_iterator_tuple(iterator_tuple)
{
} // end zip_iterator::zip_iterator()

template <typename IteratorTuple>
  template <typename OtherIteratorTuple>
    zip_iterator<IteratorTuple>
      ::zip_iterator(const zip_iterator<OtherIteratorTuple> &other,
                     typename thrust::detail::enable_if_convertible<
                       OtherIteratorTuple,
                       IteratorTuple
                     >::type *)
        :m_iterator_tuple(other.get_iterator_tuple())
{
} // end zip_iterator::zip_iterator()

template <typename IteratorTuple>
const IteratorTuple &zip_iterator<IteratorTuple>
  ::get_iterator_tuple(void) const
{
  return m_iterator_tuple;
} // end zip_iterator::get_iterator_tuple()

template <typename IteratorTuple>
  typename zip_iterator<IteratorTuple>::super_t::reference
    zip_iterator<IteratorTuple>
      ::dereference(void) const
{
  using namespace detail::tuple_impl_specific;

  return thrust::detail::tuple_host_device_transform<detail::dereference_iterator::template apply>(get_iterator_tuple(), detail::dereference_iterator());
} // end zip_iterator::dereference()

template <typename IteratorTuple>
  template <typename OtherIteratorTuple>
    bool zip_iterator<IteratorTuple>
      ::equal(const zip_iterator<OtherIteratorTuple> &other) const
{
  return get<0>(get_iterator_tuple()) == get<0>(other.get_iterator_tuple());
} // end zip_iterator::equal()

template <typename IteratorTuple>
  void zip_iterator<IteratorTuple>
    ::advance(typename super_t::difference_type n)
{
  using namespace detail::tuple_impl_specific;

  // XXX note that we use a pointer to System to dispatch to avoid
  //     default construction of a System
  typename thrust::iterator_system<zip_iterator>::type *use_me_to_dispatch = 0;

  // dispatch on system
  tuple_for_each(m_iterator_tuple,
                 detail::advance_iterator<typename super_t::difference_type>(n),
                 use_me_to_dispatch);
} // end zip_iterator::advance()

template <typename IteratorTuple>
  void zip_iterator<IteratorTuple>
    ::increment(void)
{
  using namespace detail::tuple_impl_specific;

  // XXX note that we use a pointer to System to dispatch to avoid
  //     default construction of a System
  typename thrust::iterator_system<zip_iterator>::type *use_me_to_dispatch = 0;

  // dispatch on system
  tuple_for_each(m_iterator_tuple, detail::increment_iterator(),
                 use_me_to_dispatch);
} // end zip_iterator::increment()

template <typename IteratorTuple>
  void zip_iterator<IteratorTuple>
    ::decrement(void)
{
  using namespace detail::tuple_impl_specific;

  // XXX note that we use a pointer to System to dispatch to avoid
  //     default construction of a System
  typename thrust::iterator_system<zip_iterator>::type *use_me_to_dispatch = 0;

  // dispatch on system
  tuple_for_each(m_iterator_tuple, detail::decrement_iterator(),
                 use_me_to_dispatch);
} // end zip_iterator::decrement()

template <typename IteratorTuple>
  template <typename OtherIteratorTuple>
    typename zip_iterator<IteratorTuple>::super_t::difference_type
      zip_iterator<IteratorTuple>
        ::distance_to(const zip_iterator<OtherIteratorTuple> &other) const
{
  return get<0>(other.get_iterator_tuple()) - get<0>(get_iterator_tuple());
} // end zip_iterator::distance_to()

template <typename IteratorTuple>
  zip_iterator<IteratorTuple> make_zip_iterator(IteratorTuple t)
{
  return zip_iterator<IteratorTuple>(t);
} // end make_zip_iterator()

} // end thrust

<|endoftext|>


<commit_before>#include	"World.hh"

World::World()
{
  _initWorld();
  _initWildBattles();
}

World::~World()
{
}

void		World::_initWorld()
{
  int		banki = 0;
  uint32_t	*bankptr = (uint32_t *) (rom + BANK_PTR);
  uint32_t	rel = bankptr[banki];
  uint32_t	next = bankptr[banki + 1];

  while (next > ROM_OFFSET)
    {
      _banks.push_back(std::vector<Map>());
      std::vector<Map>	&maps = _banks.back();

      for (uint32_t mapi = rel; mapi < next; mapi += 4)
	{
	  maps.push_back(Map());
	  Map		&map = maps.back();
	  uint32_t	mapaddr = *((uint32_t *) gbaMem(mapi));
	  Header	*header = (Header *) gbaMem(mapaddr);
	  DataHeader	*dheader = (DataHeader *) gbaMem(header->mapPtr);
	  TilesetHeader	*global = (TilesetHeader *) gbaMem(dheader->globalTileset);
	  TilesetHeader	*local = (TilesetHeader *) gbaMem(dheader->localTileset);
	  Map::TileAttr	*globPtr = (Map::TileAttr *) gbaMem(global->behaviorPtr);
	  Map::TileAttr	*localPtr = (Map::TileAttr *) gbaMem(local->behaviorPtr);
	  uint16_t	*d = (uint16_t *) gbaMem(dheader->data);
	  Event		*evtPtr = (Event *) gbaMem(header->evtPtr);

	  map.width = dheader->width;
	  map.height = dheader->height;
	  map.nbPersons = evtPtr->nbPersons;
	  map.nbWarps = evtPtr->nbWarps;
	  map.nbScripts = evtPtr->nbScripts;
	  map.nbSigns = evtPtr->nbSigns;
	  map.persons = (PersonEvt *) gbaMem(evtPtr->personsPtr);
	  map.warps = (WarpEvt *) gbaMem(evtPtr->warpsPtr);
	  map.scripts = (ScriptEvt *) gbaMem(evtPtr->scriptsPtr);
	  map.signs = (SignEvt *) gbaMem(evtPtr->signsPtr);
	  map.nbConnects = ((uint32_t *) gbaMem(header->connectPtr))[0];
	  map.connects = (Connection *) gbaMem(((uint32_t *) gbaMem(header->connectPtr))[1]);
	  map.scriptPtr = header->scriptPtr;
	  map.data = new Map::Node*[map.height]();
	  for (uint16_t y = 0; y < map.height; y++)
	    {
	      map.data[y] = new Map::Node[map.width]();
	      for (uint16_t x = 0; x < map.width; x++)
		{
		  uint16_t	t = d[y * map.width + x] & ((1 << 10) - 1);

		  map.data[y][x] = Map::Node(x, y);
		  map.data[y][x].status = d[y * map.width + x] >> 10;
		  map.data[y][x].tile = t;
		  map.data[y][x].attr = t < 0x280 ? globPtr + t : localPtr + t - 0x280;
		}
	    }
	}
      banki++;
      rel = next;
      next = bankptr[banki + 1];
    }
}

void		World::_initWildBattles()
{
  WildHeader	*wh = (WildHeader *) gbaMem(0x083c9cb8);

  while (wh->bank != 0xFF || wh->map != 0xFF)
    {
      Map	&map = getMap(wh->bank, wh->map);
      for (int i = 0; i < 4; i++)
	{
	  map.wildBattles[i].nbEntries = 0;
	  map.wildBattles[i].ratio = 0;
	  if (wh->entryPtr[i])
	    {
	      uint32_t	*eh = (uint32_t *) gbaMem(wh->entryPtr[i]);
	      map.wildBattles[i].ratio = eh[0];
	      map.wildBattles[i].entries = (WildEntry *) gbaMem(eh[1]);
	      map.wildBattles[i].nbEntries = (wh->entryPtr[i] - eh[1]) / 4;
	    }
	}
      wh++;
    }
}

int		World::Map::_getNextIndex(std::vector<Node*> *set)
{
  int		i = -1;
  uint32_t	min;
  uint32_t	count = 0;

  for (std::vector<Node*>::iterator it = set->begin(); it != set->end(); it++)
    {
      if (i == -1 || (*it)->f < min)
	{
	  i = count;
	  min = (*it)->f;
	}
      count++;
    }
  return (i);
}

std::vector<World::Map::Node*>*	World::Map::_rebuildPath(std::vector<Node*>* set, Node *node)
{
  if (node->from)
    _rebuildPath(set, node->from);
  set->push_back(node);
  return (set);
}

bool		checkHills(int i, int j, uint16_t next_behavior,
			   uint16_t curr_behavior)
{
  // Jump down hill
  return ((j == 1 && next_behavior == 0x3b) ||
	  (j == 1 && curr_behavior == 0x3b) ||
	  // Jump right hill
	  (i == 1 && next_behavior == 0x38) ||
	  (i == 1 && curr_behavior == 0x38) ||
	  // Jump left hill
	  (i == -1 && next_behavior == 0x39) ||
	  (i == -1 && curr_behavior == 0x39));
}

bool		checkWalkableTiles(std::vector<uint8_t> walkableTiles,
				   uint8_t status, uint16_t behavior)
{
  // Check walkable tiles (grass/tile near escalator, for now)
  return (std::find(walkableTiles.begin(),
		    walkableTiles.end(),
		    status) != walkableTiles.end() &&
	  // Check that it's not an escalator
	  behavior != 0x6b &&
	  behavior != 0x6a);
}

std::vector<World::Map::Node*>*	World::Map::findPath(uint32_t xs, uint32_t ys,
						     uint32_t xe, uint32_t ye)
{
  std::vector<Node*>	openset;
  std::vector<Node*>	closedset;
  static const uint8_t        arr[] = {0x0C,	//Grass/Road
				       0x00,	//Area around objects
				       0x10};	//Escalators
  std::vector<uint8_t>        walkableTiles(arr, arr + sizeof(arr) / sizeof(arr[0]));

  openset.push_back(new Node(xs, ys));
  openset.back()->setF(xe, ye);
  while (openset.size())
    {
      int		i = _getNextIndex(&openset);
      Node*		curr = openset[i];
      openset.erase(openset.begin() + i);
      if (curr->x == xe && curr->y == ye)
	return (_rebuildPath(new std::vector<Node*>, curr));
      closedset.push_back(curr);
      for (int j = -1; j <= 1; j++)
	{
	  for (int i = -1; i <= 1; i++)
	    {
	      int	x = curr->x + i;
	      int	y = curr->y + j;

	      // Boundaries check
	      if (x < 0 || x >= (int) width || y < 0 || y >= (int) height ||
		  (!i && !j) || (i && j))
		continue;
	      // Tile type check
	      if (!(checkHills(i, j, data[y][x].attr->behavior, data[curr->y][curr->x].attr->behavior) ||
		    checkWalkableTiles(walkableTiles, data[y][x].status, data[y][x].attr->behavior) ||
		    // Block access to hill from a lower level
		    data[y][x].attr->behavior == 0x32 ||
		    // Check if escalator is the final tile
		    (!j && (data[y][x].attr->behavior == 0x6b ||
			    data[y][x].attr->behavior == 0x6a) && x == (int) xe && y == (int) ye)))
		continue;

	      Node	*neighbor = &(data[y][x]);
	      std::vector<Node*>::iterator	it = std::find(closedset.begin(),
							       closedset.end(),
							       neighbor);
	      uint32_t	g = curr->g + (!i || !j ? 10 : 14);
	      if (it != closedset.end() && g >= neighbor->g)
		continue;
	      if (it == closedset.end() || g < neighbor->g)
		{
		  neighbor->from = curr;
		  neighbor->setG(g);
		  neighbor->setF(xe, ye);
		  if (std::find(openset.begin(), openset.end(), neighbor) == openset.end())
		    openset.push_back(neighbor);
		}
	    }
	}
    }
  return (NULL);
}
<commit_msg>add: avoid high grass<commit_after>#include	"World.hh"

World::World()
{
  _initWorld();
  _initWildBattles();
}

World::~World()
{
}

void		World::_initWorld()
{
  int		banki = 0;
  uint32_t	*bankptr = (uint32_t *) (rom + BANK_PTR);
  uint32_t	rel = bankptr[banki];
  uint32_t	next = bankptr[banki + 1];

  while (next > ROM_OFFSET)
    {
      _banks.push_back(std::vector<Map>());
      std::vector<Map>	&maps = _banks.back();

      for (uint32_t mapi = rel; mapi < next; mapi += 4)
	{
	  maps.push_back(Map());
	  Map		&map = maps.back();
	  uint32_t	mapaddr = *((uint32_t *) gbaMem(mapi));
	  Header	*header = (Header *) gbaMem(mapaddr);
	  DataHeader	*dheader = (DataHeader *) gbaMem(header->mapPtr);
	  TilesetHeader	*global = (TilesetHeader *) gbaMem(dheader->globalTileset);
	  TilesetHeader	*local = (TilesetHeader *) gbaMem(dheader->localTileset);
	  Map::TileAttr	*globPtr = (Map::TileAttr *) gbaMem(global->behaviorPtr);
	  Map::TileAttr	*localPtr = (Map::TileAttr *) gbaMem(local->behaviorPtr);
	  uint16_t	*d = (uint16_t *) gbaMem(dheader->data);
	  Event		*evtPtr = (Event *) gbaMem(header->evtPtr);

	  map.width = dheader->width;
	  map.height = dheader->height;
	  map.nbPersons = evtPtr->nbPersons;
	  map.nbWarps = evtPtr->nbWarps;
	  map.nbScripts = evtPtr->nbScripts;
	  map.nbSigns = evtPtr->nbSigns;
	  map.persons = (PersonEvt *) gbaMem(evtPtr->personsPtr);
	  map.warps = (WarpEvt *) gbaMem(evtPtr->warpsPtr);
	  map.scripts = (ScriptEvt *) gbaMem(evtPtr->scriptsPtr);
	  map.signs = (SignEvt *) gbaMem(evtPtr->signsPtr);
	  map.nbConnects = ((uint32_t *) gbaMem(header->connectPtr))[0];
	  map.connects = (Connection *) gbaMem(((uint32_t *) gbaMem(header->connectPtr))[1]);
	  map.scriptPtr = header->scriptPtr;
	  map.data = new Map::Node*[map.height]();
	  for (uint16_t y = 0; y < map.height; y++)
	    {
	      map.data[y] = new Map::Node[map.width]();
	      for (uint16_t x = 0; x < map.width; x++)
		{
		  uint16_t	t = d[y * map.width + x] & ((1 << 10) - 1);

		  map.data[y][x] = Map::Node(x, y);
		  map.data[y][x].status = d[y * map.width + x] >> 10;
		  map.data[y][x].tile = t;
		  map.data[y][x].attr = t < 0x280 ? globPtr + t : localPtr + t - 0x280;
		}
	    }
	}
      banki++;
      rel = next;
      next = bankptr[banki + 1];
    }
}

void		World::_initWildBattles()
{
  WildHeader	*wh = (WildHeader *) gbaMem(0x083c9cb8);

  while (wh->bank != 0xFF || wh->map != 0xFF)
    {
      Map	&map = getMap(wh->bank, wh->map);
      for (int i = 0; i < 4; i++)
	{
	  map.wildBattles[i].nbEntries = 0;
	  map.wildBattles[i].ratio = 0;
	  if (wh->entryPtr[i])
	    {
	      uint32_t	*eh = (uint32_t *) gbaMem(wh->entryPtr[i]);
	      map.wildBattles[i].ratio = eh[0];
	      map.wildBattles[i].entries = (WildEntry *) gbaMem(eh[1]);
	      map.wildBattles[i].nbEntries = (wh->entryPtr[i] - eh[1]) / 4;
	    }
	}
      wh++;
    }
}

int		World::Map::_getNextIndex(std::vector<Node*> *set)
{
  int		i = -1;
  uint32_t	min;
  uint32_t	count = 0;

  for (std::vector<Node*>::iterator it = set->begin(); it != set->end(); it++)
    {
      if (i == -1 || (*it)->f < min)
	{
	  i = count;
	  min = (*it)->f;
	}
      count++;
    }
  return (i);
}

std::vector<World::Map::Node*>*	World::Map::_rebuildPath(std::vector<Node*>* set, Node *node)
{
  if (node->from)
    _rebuildPath(set, node->from);
  set->push_back(node);
  return (set);
}

bool		checkHills(int i, int j, uint16_t next_behavior,
			   uint16_t curr_behavior)
{
  // Jump down hill
  return ((j == 1 && next_behavior == 0x3b) ||
	  (j == 1 && curr_behavior == 0x3b) ||
	  // Jump right hill
	  (i == 1 && next_behavior == 0x38) ||
	  (i == 1 && curr_behavior == 0x38) ||
	  // Jump left hill
	  (i == -1 && next_behavior == 0x39) ||
	  (i == -1 && curr_behavior == 0x39));
}

bool		checkWalkableTiles(std::vector<uint8_t> walkableTiles,
				   uint8_t status, uint16_t behavior)
{
  // Check walkable tiles (grass/tile near escalator, for now)
  return (std::find(walkableTiles.begin(),
		    walkableTiles.end(),
		    status) != walkableTiles.end() &&
	  // Check that it's not an escalator
	  behavior != 0x6b &&
	  behavior != 0x6a);
}

std::vector<World::Map::Node*>*	World::Map::findPath(uint32_t xs, uint32_t ys,
						     uint32_t xe, uint32_t ye)
{
  std::vector<Node*>	openset;
  std::vector<Node*>	closedset;
  static const uint8_t	arr[] = {0x0C,	//Grass/Road
				 0x00,	//Area around objects
				 0x10};	//Escalators
  std::vector<uint8_t>	walkableTiles(arr, arr + sizeof(arr) / sizeof(arr[0]));

  openset.push_back(new Node(xs, ys));
  openset.back()->setF(xe, ye);
  while (openset.size())
    {
      int		i = _getNextIndex(&openset);
      Node*		curr = openset[i];
      openset.erase(openset.begin() + i);
      if (curr->x == xe && curr->y == ye)
	return (_rebuildPath(new std::vector<Node*>, curr));
      closedset.push_back(curr);
      for (int j = -1; j <= 1; j++)
	{
	  for (int i = -1; i <= 1; i++)
	    {
	      int	x = curr->x + i;
	      int	y = curr->y + j;

	      // Boundaries check
	      if (x < 0 || x >= (int) width || y < 0 || y >= (int) height ||
		  (!i && !j) || (i && j))
		continue;
	      // Tile type check
	      if (!(checkHills(i, j, data[y][x].attr->behavior, data[curr->y][curr->x].attr->behavior) ||
		    checkWalkableTiles(walkableTiles, data[y][x].status, data[y][x].attr->behavior) ||
		    // Block access to hill from a lower level
		    data[y][x].attr->behavior == 0x32 ||
		    // Check if escalator is the final tile
		    (!j && (data[y][x].attr->behavior == 0x6b ||
			    data[y][x].attr->behavior == 0x6a) && x == (int) xe && y == (int) ye)))
		continue;

	      Node				*neighbor = &(data[y][x]);
	      std::vector<Node*>::iterator	it = std::find(closedset.begin(),
							       closedset.end(),
							       neighbor);
	      uint32_t	g = curr->g + 10;
	      if (data[y][x].attr->behavior == 0x0202)
		g += 20; // Grass "fear"
	      if (it != closedset.end() && g >= neighbor->g)
		continue;
	      if (it == closedset.end() || g < neighbor->g)
		{
		  neighbor->from = curr;
		  neighbor->setG(g);
		  neighbor->setF(xe, ye);
		  if (std::find(openset.begin(), openset.end(), neighbor) == openset.end())
		    openset.push_back(neighbor);
		}
	    }
	}
    }
  return (NULL);
}
<|endoftext|>