<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROI_QB_MUL_1.png}
//    OUTPUTS: {PanTexOutput.tif}, {pretty_PanTexInput.png}, {pretty_PanTexOutput.png}
//  Software Guide : EndCommandLineArgs

#include "itkMacro.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"

// Software Guide : BeginLatex
//
// This example illustrates the use of the
// \doxygen{otb}{ScalarImageToPanTexTextureFilter}. This texture parameter was
// first introduced in \cite{PanTex} and is very useful for urban area
// detection.
// \relatedClasses
//  \begin{itemize}
//  \item \doxygen{otb}{ScalarImageToTexturesFilter}
//  \item \doxygen{otb}{ScalarIamgeToAdvancedTexturesFilter}
//  \end{itemize}
//
// The first step required to use this filter is to include its header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbScalarImageToPanTexTextureFilter.h"
// Software Guide : EndCodeSnippet

int main(int argc, char * argv[])
{
  // Parse command line parameters
  if (argc != 5)
    {
    std::cerr << "Usage: " << argv[0] << " <inputImage> ";
    std::cerr << " <outputImage> <inputRescaled> <outputRescaled> ";
    std::cerr << std::endl;
    return EXIT_FAILURE;
    }

  const char* infname   = argv[1];
  const char* outfname  = argv[2];
  const char* inprettyfname  = argv[3];
  const char* outprettyfname  = argv[4];

  typedef double PixelType;
  const int Dimension = 2;
  typedef otb::Image<PixelType, Dimension> ImageType;

  // Software Guide : BeginLatex
//
// After defining the types for the pixels and the images used in the
// example, we define the type for the PanTex filter. It is
// templated by the input and output image types.
//
// Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::ScalarImageToPanTexTextureFilter
  <ImageType, ImageType> PanTexTextureFilterType;
  // Software Guide : EndCodeSnippet
  typedef otb::ImageFileReader<ImageType> ReaderType;
  typedef otb::ImageFileWriter<ImageType> WriterType;

  ReaderType::Pointer reader  = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName(infname);
  writer->SetFileName(outfname);

  // Software Guide : BeginLatex
//
// We can now instatiate the filter.
//
// Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  PanTexTextureFilterType::Pointer textureFilter = PanTexTextureFilterType::New();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Then, we set the parameters of the filter.The radius of
  // the neighborhood to compute the texture.
  // The number of bins per axis for histogram generation (it is the
  // size of the co-occurrence matrix). Moreover, we have to specify
  // the Min/Max in the input image. In the example, image Min/Max is set
  // by the user to 0 and 255. Alternatively you can use the class \doxygen{itk}{MinimumMaximumImageCalculator}
  // to calculate these values.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  PanTexTextureFilterType::SizeType sradius;
  sradius.Fill(4);
  textureFilter->SetNumberOfBinsPerAxis(8);
  textureFilter->SetRadius(sradius);
  textureFilter->SetInputImageMinimum(0);
  textureFilter->SetInputImageMaximum(255);
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We can now plug the pipeline and trigger the execution by calling
  // the \code{Update} method of the writer.
  //
  // Software Guide : EndLatex
  // Software Guide : BeginCodeSnippet
  textureFilter->SetInput(reader->GetOutput());
  writer->SetInput(textureFilter->GetOutput());

  writer->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  // Figure~\ref{fig:PANTEXFILTER} shows the result of applying
  // the PanTex computation.
  // \begin{figure}
  // \center
  // \includegraphics[width=0.40\textwidth]{pretty_PanTexInput.eps}
  // \includegraphics[width=0.40\textwidth]{pretty_PanTexOutput.eps}
  // \itkcaption[PanTex Filter]{Result of applying the
  // \doxygen{otb}{ScalarImageToPanTexTextureFilter} to an image. From left to right:
  // original image, PanTex feature.}
  // \label{fig:PANTEXFILTER}
  // \end{figure}
  //
  //  Software Guide : EndLatex

  // Pretty image creation for printing

  typedef otb::Image<unsigned char,
      Dimension>
  OutputPrettyImageType;
  typedef otb::ImageFileWriter<OutputPrettyImageType>
  WriterPrettyOutputType;
  typedef itk::RescaleIntensityImageFilter<ImageType,
      OutputPrettyImageType>
  RescalerOutputType;

  RescalerOutputType::Pointer     outputRescaler     = RescalerOutputType::New();
  WriterPrettyOutputType::Pointer prettyOutputWriter =
    WriterPrettyOutputType::New();
  outputRescaler->SetInput(textureFilter->GetOutput());
  outputRescaler->SetOutputMinimum(0);
  outputRescaler->SetOutputMaximum(255);
  prettyOutputWriter->SetFileName(outprettyfname);
  prettyOutputWriter->SetInput(outputRescaler->GetOutput());

  prettyOutputWriter->Update();

  outputRescaler->SetInput(reader->GetOutput());
  outputRescaler->SetOutputMinimum(0);
  outputRescaler->SetOutputMaximum(255);
  prettyOutputWriter->SetFileName(inprettyfname);
  prettyOutputWriter->SetInput(outputRescaler->GetOutput());

  prettyOutputWriter->Update();

  return EXIT_SUCCESS;
}
<commit_msg>DOC: fix a typo<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

//  Software Guide : BeginCommandLineArgs
//    INPUTS: {ROI_QB_MUL_1.png}
//    OUTPUTS: {PanTexOutput.tif}, {pretty_PanTexInput.png}, {pretty_PanTexOutput.png}
//  Software Guide : EndCommandLineArgs

#include "itkMacro.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"

// Software Guide : BeginLatex
//
// This example illustrates the use of the
// \doxygen{otb}{ScalarImageToPanTexTextureFilter}. This texture parameter was
// first introduced in \cite{PanTex} and is very useful for urban area
// detection.
// \relatedClasses
//  \begin{itemize}
//  \item \doxygen{otb}{ScalarImageToTexturesFilter}
//  \item \doxygen{otb}{ScalarImageToAdvancedTexturesFilter}
//  \end{itemize}
//
// The first step required to use this filter is to include its header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbScalarImageToPanTexTextureFilter.h"
// Software Guide : EndCodeSnippet

int main(int argc, char * argv[])
{
  // Parse command line parameters
  if (argc != 5)
    {
    std::cerr << "Usage: " << argv[0] << " <inputImage> ";
    std::cerr << " <outputImage> <inputRescaled> <outputRescaled> ";
    std::cerr << std::endl;
    return EXIT_FAILURE;
    }

  const char* infname   = argv[1];
  const char* outfname  = argv[2];
  const char* inprettyfname  = argv[3];
  const char* outprettyfname  = argv[4];

  typedef double PixelType;
  const int Dimension = 2;
  typedef otb::Image<PixelType, Dimension> ImageType;

  // Software Guide : BeginLatex
//
// After defining the types for the pixels and the images used in the
// example, we define the type for the PanTex filter. It is
// templated by the input and output image types.
//
// Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  typedef otb::ScalarImageToPanTexTextureFilter
  <ImageType, ImageType> PanTexTextureFilterType;
  // Software Guide : EndCodeSnippet
  typedef otb::ImageFileReader<ImageType> ReaderType;
  typedef otb::ImageFileWriter<ImageType> WriterType;

  ReaderType::Pointer reader  = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();

  reader->SetFileName(infname);
  writer->SetFileName(outfname);

  // Software Guide : BeginLatex
//
// We can now instatiate the filter.
//
// Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  PanTexTextureFilterType::Pointer textureFilter = PanTexTextureFilterType::New();
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // Then, we set the parameters of the filter.The radius of
  // the neighborhood to compute the texture.
  // The number of bins per axis for histogram generation (it is the
  // size of the co-occurrence matrix). Moreover, we have to specify
  // the Min/Max in the input image. In the example, image Min/Max is set
  // by the user to 0 and 255. Alternatively you can use the class \doxygen{itk}{MinimumMaximumImageCalculator}
  // to calculate these values.
  //
  // Software Guide : EndLatex

  // Software Guide : BeginCodeSnippet
  PanTexTextureFilterType::SizeType sradius;
  sradius.Fill(4);
  textureFilter->SetNumberOfBinsPerAxis(8);
  textureFilter->SetRadius(sradius);
  textureFilter->SetInputImageMinimum(0);
  textureFilter->SetInputImageMaximum(255);
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginLatex
  //
  // We can now plug the pipeline and trigger the execution by calling
  // the \code{Update} method of the writer.
  //
  // Software Guide : EndLatex
  // Software Guide : BeginCodeSnippet
  textureFilter->SetInput(reader->GetOutput());
  writer->SetInput(textureFilter->GetOutput());

  writer->Update();
  // Software Guide : EndCodeSnippet

  //  Software Guide : BeginLatex
  // Figure~\ref{fig:PANTEXFILTER} shows the result of applying
  // the PanTex computation.
  // \begin{figure}
  // \center
  // \includegraphics[width=0.40\textwidth]{pretty_PanTexInput.eps}
  // \includegraphics[width=0.40\textwidth]{pretty_PanTexOutput.eps}
  // \itkcaption[PanTex Filter]{Result of applying the
  // \doxygen{otb}{ScalarImageToPanTexTextureFilter} to an image. From left to right:
  // original image, PanTex feature.}
  // \label{fig:PANTEXFILTER}
  // \end{figure}
  //
  //  Software Guide : EndLatex

  // Pretty image creation for printing

  typedef otb::Image<unsigned char,
      Dimension>
  OutputPrettyImageType;
  typedef otb::ImageFileWriter<OutputPrettyImageType>
  WriterPrettyOutputType;
  typedef itk::RescaleIntensityImageFilter<ImageType,
      OutputPrettyImageType>
  RescalerOutputType;

  RescalerOutputType::Pointer     outputRescaler     = RescalerOutputType::New();
  WriterPrettyOutputType::Pointer prettyOutputWriter =
    WriterPrettyOutputType::New();
  outputRescaler->SetInput(textureFilter->GetOutput());
  outputRescaler->SetOutputMinimum(0);
  outputRescaler->SetOutputMaximum(255);
  prettyOutputWriter->SetFileName(outprettyfname);
  prettyOutputWriter->SetInput(outputRescaler->GetOutput());

  prettyOutputWriter->Update();

  outputRescaler->SetInput(reader->GetOutput());
  outputRescaler->SetOutputMinimum(0);
  outputRescaler->SetOutputMaximum(255);
  prettyOutputWriter->SetFileName(inprettyfname);
  prettyOutputWriter->SetInput(outputRescaler->GetOutput());

  prettyOutputWriter->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "Octree.hpp"
#include <Core/AScene.hh>
#include <Components/MeshRenderer.hh>
#include <Core/EntityFilter.hpp>
#include <Components/CameraComponent.hpp>
#include <Utils/Frustum.hpp>

using namespace AGE;

Octree::USER_OBJECT_ID Octree::addElement(COMPONENT_ID componentType, const Entity &entity)
{
	Octree::USER_OBJECT_ID res = USER_OBJECT_ID(-1);
	if (!_freeUserObjects.empty())
	{
		res = _freeUserObjects.top();
		_freeUserObjects.pop();
	}
	else
	{
		res = _userObjectCounter++;
	}

	_commands.push(Command());
	_commands.back().entity = entity;
	_commands.back().commandType.set(CommandType::Create);
	_commands.back().id = res;
	_commands.back().componentType = componentType;
	return res;
}

void Octree::removeElement(Octree::USER_OBJECT_ID id)
{
	_freeUserObjects.push(id);
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().commandType.set(CommandType::Delete);
	assert(id != (std::size_t)(-1));
}

void Octree::setPosition(const glm::vec3 &v, Octree::USER_OBJECT_ID id)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().position = v;
	_commands.back().commandType.set(CommandType::Position);
}
void Octree::setOrientation(const glm::quat &v, Octree::USER_OBJECT_ID id)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().orientation = v;
	_commands.back().commandType.set(CommandType::Orientation);
}

void Octree::setScale(const glm::vec3 &v, Octree::USER_OBJECT_ID id)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().scale = v;
	_commands.back().commandType.set(CommandType::Scale);
}

void Octree::setPosition(const glm::vec3 &v, const std::array<Octree::USER_OBJECT_ID, MAX_CPT_NUMBER> &ids)
{
	for (auto &e : ids)
		setPosition(v, e);
}

void Octree::setOrientation(const glm::quat &v, const std::array<Octree::USER_OBJECT_ID, MAX_CPT_NUMBER> &ids)
{
	for (auto &e : ids)
		setOrientation(v, e);
}

void Octree::setScale(const glm::vec3 &v, const std::array<Octree::USER_OBJECT_ID, MAX_CPT_NUMBER> &ids)
{
	for (auto &e : ids)
		setScale(v, e);
}

void Octree::updateGeometry(USER_OBJECT_ID id
	, const std::vector<gl::Key<gl::Vertices>> &glvertices
	, const std::vector<gl::Key<gl::Indices>> &glindices
	, const std::vector<BoundingInfos> &boundings)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().glindices = glindices;
	_commands.back().glvertices = glvertices;
	_commands.back().boundings = boundings;
	_commands.back().commandType.set(CommandType::Geometry);
}

//-----------------------------------------------------------------

Octree::CULLABLE_ID Octree::addCullableObject(Octree::USER_OBJECT_ID uid)
{
	CULLABLE_ID res = CULLABLE_ID(-1);
	CullableObject *co = nullptr;
	if (!_freeCullableObjects.empty())
	{
		res = _freeCullableObjects.top();
		_freeCullableObjects.pop();
		co = &(_cullableObjects[res]);
	}
	else
	{
		res = _cullableObjects.size();
		_cullableObjects.emplace_back(CullableObject());
		co = &(_cullableObjects.back());
	}
	co->userObjectId = uid;
	co->id = res;
	co->active = true;
	return res;
}

void Octree::removeCullableObject(CULLABLE_ID id)
{
	_freeCullableObjects.push(id);
	_cullableObjects[id].active = false;
	assert(id != (std::size_t)(-1));
}

void Octree::update()
{
	while (!_commands.empty())
	{
		//process command
		auto &command = _commands.front();

		if (command.commandType.at(CommandType::Create))
		{
			UserObject *ue = nullptr;
			if (command.id <= _userObjects.size())
			{
				_userObjects.push_back(UserObject());
				ue = &_userObjects.back();
			}
			else
			{
				ue = &_userObjects[command.id];
			}
			ue->id = command.id;
			ue->componentType = command.componentType;
			ue->entity = command.entity;
			ue->active = true;
		}
		else if (command.commandType.at(CommandType::Delete))
		{
			auto &ue = _userObjects[command.id];
			_freeUserObjects.push(command.id);
			for (auto &e : ue.collection)
			{
				removeCullableObject(e);
			}
			ue.collection.clear();
			ue.active = false;
		}
		else if (command.commandType.at(CommandType::Geometry))
		{
			auto &ue = _userObjects[command.id];
			for (auto &e : ue.collection)
			{
				removeCullableObject(e);
			}
			ue.collection.clear();
			for (std::size_t i = 0; i < command.glindices.size(); ++i)
			{
				auto id = addCullableObject(command.id);
				_cullableObjects[id].bounding = command.boundings[i];
				_cullableObjects[id].glvertices = command.glvertices[i];
				_cullableObjects[id].glindices = command.glindices[i];
				_cullableObjects[id].position = ue.position;
				_cullableObjects[id].orientation = ue.orientation;
				_cullableObjects[id].scale = ue.scale;
			}
		}
		else if (command.commandType.at(CommandType::Position))
		{
			auto &ue = _userObjects[command.id];
			ue.position = command.position;
			for (auto &e : ue.collection)
			{
				_cullableObjects[e].position = ue.position;
			}
		}
		else if (command.commandType.at(CommandType::Scale))
		{
			auto &ue = _userObjects[command.id];
			ue.scale = command.scale;
			for (auto &e : ue.collection)
			{
				_cullableObjects[e].scale = ue.scale;
			}
		}
		else if (command.commandType.at(CommandType::Orientation))
		{
			auto &ue = _userObjects[command.id];
			ue.orientation = command.orientation;
			for (auto &e : ue.collection)
			{
				_cullableObjects[e].orientation = ue.orientation;
			}
		}
		_commands.pop();
	}

	static EntityFilter *filter = nullptr;
	if (!filter)
	{
		filter = new EntityFilter(std::move(scene));
		filter->requireComponent<Component::CameraComponent>();
	}

	if (filter->getCollection().size() == 0)
		return;
	auto cameraEntity = *(filter->getCollection().begin());
	auto camera = scene.lock()->getComponent<Component::CameraComponent>(cameraEntity);

	Frustum frustum;
	static float rot = 0.0f;
	rot += 1.0f;
	auto m = camera->projection * camera->lookAtTransform;
	frustum.setMatrix(m, true);
	std::uint64_t drawed = 0;
	std::uint64_t total = 0;
	for (auto &e : _cullableObjects)
	{
		if (e.active)
			++total;
		if (e.active && frustum.pointIn(e.position) == true)
		{
			//std::cout << e.entity.getId() << "  ";
			auto &uo = _userObjects[e.userObjectId];
			auto cpt = scene.lock()->getComponent(uo.entity, uo.componentType);
			if (cpt)
			{
				auto c = dynamic_cast<AGE::ComponentBehavior::Cullable*>(cpt);
				c->draw = true;
				++drawed;
			}
			else
			{
				assert(false);
			}
		}
	}
//	std::cout << "Drawed : " << drawed << " / " << total << std::endl;
}<commit_msg>temporary draw for debug<commit_after>#include "Octree.hpp"
#include <Core/AScene.hh>
#include <Components/MeshRenderer.hh>
#include <Core/EntityFilter.hpp>
#include <Components/CameraComponent.hpp>
#include <Utils/Frustum.hpp>

using namespace AGE;

Octree::USER_OBJECT_ID Octree::addElement(COMPONENT_ID componentType, const Entity &entity)
{
	Octree::USER_OBJECT_ID res = USER_OBJECT_ID(-1);
	if (!_freeUserObjects.empty())
	{
		res = _freeUserObjects.top();
		_freeUserObjects.pop();
	}
	else
	{
		res = _userObjectCounter++;
	}

	_commands.push(Command());
	_commands.back().entity = entity;
	_commands.back().commandType.set(CommandType::Create);
	_commands.back().id = res;
	_commands.back().componentType = componentType;
	return res;
}

void Octree::removeElement(Octree::USER_OBJECT_ID id)
{
	_freeUserObjects.push(id);
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().commandType.set(CommandType::Delete);
	assert(id != (std::size_t)(-1));
}

void Octree::setPosition(const glm::vec3 &v, Octree::USER_OBJECT_ID id)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().position = v;
	_commands.back().commandType.set(CommandType::Position);
}
void Octree::setOrientation(const glm::quat &v, Octree::USER_OBJECT_ID id)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().orientation = v;
	_commands.back().commandType.set(CommandType::Orientation);
}

void Octree::setScale(const glm::vec3 &v, Octree::USER_OBJECT_ID id)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().scale = v;
	_commands.back().commandType.set(CommandType::Scale);
}

void Octree::setPosition(const glm::vec3 &v, const std::array<Octree::USER_OBJECT_ID, MAX_CPT_NUMBER> &ids)
{
	for (auto &e : ids)
		setPosition(v, e);
}

void Octree::setOrientation(const glm::quat &v, const std::array<Octree::USER_OBJECT_ID, MAX_CPT_NUMBER> &ids)
{
	for (auto &e : ids)
		setOrientation(v, e);
}

void Octree::setScale(const glm::vec3 &v, const std::array<Octree::USER_OBJECT_ID, MAX_CPT_NUMBER> &ids)
{
	for (auto &e : ids)
		setScale(v, e);
}

void Octree::updateGeometry(USER_OBJECT_ID id
	, const std::vector<gl::Key<gl::Vertices>> &glvertices
	, const std::vector<gl::Key<gl::Indices>> &glindices
	, const std::vector<BoundingInfos> &boundings)
{
	_commands.push(Command());
	_commands.back().id = id;
	_commands.back().glindices = glindices;
	_commands.back().glvertices = glvertices;
	_commands.back().boundings = boundings;
	_commands.back().commandType.set(CommandType::Geometry);
}

//-----------------------------------------------------------------

Octree::CULLABLE_ID Octree::addCullableObject(Octree::USER_OBJECT_ID uid)
{
	CULLABLE_ID res = CULLABLE_ID(-1);
	CullableObject *co = nullptr;
	if (!_freeCullableObjects.empty())
	{
		res = _freeCullableObjects.top();
		_freeCullableObjects.pop();
		co = &(_cullableObjects[res]);
	}
	else
	{
		res = _cullableObjects.size();
		_cullableObjects.emplace_back(CullableObject());
		co = &(_cullableObjects.back());
	}
	co->userObjectId = uid;
	co->id = res;
	co->active = true;
	return res;
}

void Octree::removeCullableObject(CULLABLE_ID id)
{
	_freeCullableObjects.push(id);
	_cullableObjects[id].active = false;
	assert(id != (std::size_t)(-1));
}

void Octree::update()
{
	while (!_commands.empty())
	{
		//process command
		auto &command = _commands.front();

		if (command.commandType.at(CommandType::Create))
		{
			UserObject *ue = nullptr;
			if (command.id <= _userObjects.size())
			{
				_userObjects.push_back(UserObject());
				ue = &_userObjects.back();
			}
			else
			{
				ue = &_userObjects[command.id];
			}
			ue->id = command.id;
			ue->componentType = command.componentType;
			ue->entity = command.entity;
			ue->active = true;
		}
		else if (command.commandType.at(CommandType::Delete))
		{
			auto &ue = _userObjects[command.id];
			_freeUserObjects.push(command.id);
			for (auto &e : ue.collection)
			{
				removeCullableObject(e);
			}
			ue.collection.clear();
			ue.active = false;
		}
		else if (command.commandType.at(CommandType::Geometry))
		{
			auto &ue = _userObjects[command.id];
			for (auto &e : ue.collection)
			{
				removeCullableObject(e);
			}
			ue.collection.clear();
			for (std::size_t i = 0; i < command.glindices.size(); ++i)
			{
				auto id = addCullableObject(command.id);
				_cullableObjects[id].bounding = command.boundings[i];
				_cullableObjects[id].glvertices = command.glvertices[i];
				_cullableObjects[id].glindices = command.glindices[i];
				_cullableObjects[id].position = ue.position;
				_cullableObjects[id].orientation = ue.orientation;
				_cullableObjects[id].scale = ue.scale;
			}
		}
		else if (command.commandType.at(CommandType::Position))
		{
			auto &ue = _userObjects[command.id];
			ue.position = command.position;
			for (auto &e : ue.collection)
			{
				_cullableObjects[e].position = ue.position;
			}
		}
		else if (command.commandType.at(CommandType::Scale))
		{
			auto &ue = _userObjects[command.id];
			ue.scale = command.scale;
			for (auto &e : ue.collection)
			{
				_cullableObjects[e].scale = ue.scale;
			}
		}
		else if (command.commandType.at(CommandType::Orientation))
		{
			auto &ue = _userObjects[command.id];
			ue.orientation = command.orientation;
			for (auto &e : ue.collection)
			{
				_cullableObjects[e].orientation = ue.orientation;
			}
		}
		_commands.pop();
	}

	static EntityFilter *filter = nullptr;
	if (!filter)
	{
		filter = new EntityFilter(std::move(scene));
		filter->requireComponent<Component::CameraComponent>();
	}

	if (filter->getCollection().size() == 0)
		return;
	auto cameraEntity = *(filter->getCollection().begin());
	auto camera = scene.lock()->getComponent<Component::CameraComponent>(cameraEntity);

	Frustum frustum;
	static float rot = 0.0f;
	rot += 1.0f;
	auto m = camera->projection * camera->lookAtTransform;
	frustum.setMatrix(m, true);
	std::uint64_t drawed = 0;
	std::uint64_t total = 0;

	//TMP
	for (auto &e : _userObjects)
	{
		if (e.active)
		{
			auto cpt = scene.lock()->getComponent(e.entity, e.componentType);
			if (cpt)
			{
				auto c = dynamic_cast<AGE::ComponentBehavior::Cullable*>(cpt);
				c->draw = true;
				++drawed;
			}
		}
	}
	//!TMP

	for (auto &e : _cullableObjects)
	{
		if (e.active)
			++total;
		if (e.active && frustum.pointIn(e.position) == true)
		{
			//std::cout << e.entity.getId() << "  ";
			auto &uo = _userObjects[e.userObjectId];
			auto cpt = scene.lock()->getComponent(uo.entity, uo.componentType);
			if (cpt)
			{
				auto c = dynamic_cast<AGE::ComponentBehavior::Cullable*>(cpt);
				c->draw = true;
				++drawed;
			}
			else
			{
				assert(false);
			}
		}
	}
//	std::cout << "Drawed : " << drawed << " / " << total << std::endl;
}<|endoftext|>


<commit_before>// Copyright [2016] <Salomão Rodrigues Jacinto>
#ifndef PILHA_HPP
#define PILHA_HPP

/**
 * @brief  		Implementação de uma estrutura de Pilha em C++
 *
 * @tparam  	T			Ponteiro para o início da Pilha
 *
 * @param  		top			Armazena o topo da Pilha
 * @param  		tamanho		Armazena o tamanho da Pilha
 */
template<typename T>
class Pilha {
 private:
	const int MAXPILHA = 100;
	T* m_dados;
	int top;
	int tamanho;

 public:
	/**
	 * @brief  		Construtor da Classe Pilha
	 *
 	 * @details  	Valor do tamanho definido em uma constante como 100
	 */
	Pilha() {
		top = -1;
		m_dados = new T[MAXPILHA];
		tamanho = MAXPILHA;
	}
	/**
	 * @brief  		Construtor da Classe Pilha
	 *
	 * @param  		t		Valor para o tamanho da pilha
	 */
	explicit Pilha<T>(int t) {
		top = -1;
		m_dados = new T[t];
		tamanho = t;
	}
	/**
	 * @brief  		Retorna o valor armazenado no topo da pilha
	 */
	T topo() {
		if (PilhaVazia()) {
			throw "Pilha Vazia";
		} else {
			return m_dados[top];
		}
	}
	/**
	 * @brief      Retorna a posição do topo
	 */
	int getPosTopo() {
		if (PilhaVazia()) {
			throw "Pilha Vazia";
		} else {
			return top;
		}
	}
	/**
	 * @brief      Limpa a pilha
	 */
	void limparPilha() {
		top = -1;
	}
	/**
	 * @brief      Checa se a pilha está vazia
	 *
	 * @return     Retorna true caso a pilha esteja vazia
	 */
	bool PilhaVazia() {
		if (top == -1) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * @brief      Checa se a pilha está cheia
	 *
	 * @return     Retorna true caso a pilha esteja cheia
	 */
	bool PilhaCheia() {
		if (top == tamanho-1) {
			return true;
		} else {
			return false;
		}
	}
	/**
	 * @brief      Adiciona um dado a pilha
	 *
	 * @param  		dado  Dado genérico, podendo ser um inteiro, float...
	 */
	void empilha(T dado) {
		if (PilhaCheia()) {
			throw "Pilha Cheia!";
		} else {
			top++;
			m_dados[top] = dado;
		}
	}
	/**
	 * @brief      Retira o último valor colocado na pilha
	 */
	T desempilha() {
		if (PilhaVazia()) {
			throw "Pilha Vazia!";
		} else {
			top--;
			return m_dados[top+1];
		}
	}
};
#endif  // PILHA_HPP
<commit_msg>Delete Pilha.hpp<commit_after><|endoftext|>


<commit_before>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2016 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  glm/test/gtx_utilities.cpp                                                      */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// includes, system

#include <array>                 // std::array<>
#include <glm/gtc/constants.hpp> // glm::pi
#include <glm/gtc/random.hpp>    // glm::*Rand
#include <glm/gtc/vec1.hpp>      // glm::vec1
#include <glm/gtx/io.hpp>        // glm::operator<<
#include <glm/gtx/transform.hpp> // glm::rotate, glm::scale, glm::translate>

// includes, project

#include <glm/gtx/utilities.hpp>

#define HUGH_USE_TRACE
#undef HUGH_USE_TRACE
#include <hugh/support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/mpl/list.hpp>

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_op_literal_deg)
{
#if defined(_MSC_VER) && (_MSC_VER <= 1900)
  BOOST_CHECK(glm::pi<double>() == 180.0 _deg);

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "glm::pi<double>():" << glm::pi<double>()
                     << " =?= 180.0_deg:"    << 180.0 _deg);
#else
  BOOST_CHECK(glm::pi<double>() == 180.0_deg);

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "glm::pi<double>():" << glm::pi<double>()
                     << " =?= 180.0_deg:"    << 180.0_deg);
#endif
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_op_literal_rad)
{
#if defined(_MSC_VER) && (_MSC_VER <= 1900)
  BOOST_CHECK(glm::pi<double>() == 180.0 _deg);

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "glm::pi<double>():" << glm::pi<double>()
                     << " =?= 180.0_deg:"    << 180.0 _deg);
#else
  BOOST_CHECK(180.0_deg == glm::pi<double>());

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "180.0_deg:"              << 180.0_deg
                     << " =?= glm::pi<double>():" << glm::pi<double>());
#endif
}

using rev_types = boost::mpl::list<glm::vec1,  glm::vec2,  glm::vec3,  glm::vec4,
                                   glm::dvec1, glm::dvec2, glm::dvec3, glm::dvec4>;

BOOST_AUTO_TEST_CASE_TEMPLATE(test_hugh_glm_gtx_utilities_rev, T, rev_types)
{
  BOOST_CHECK(glm::rev(T(glm::two_pi<typename T::value_type>())) == T(0.0));
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_sgn)
{
  BOOST_CHECK(glm::sgn(-1) < 0);
  BOOST_CHECK(glm::sgn(+1) > 0);
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_decompose)
{
  glm::mat4 const      m;
  glm::decompose const d(m);

  BOOST_CHECK(glm::mat4() == d.rotation);
  BOOST_CHECK(glm::mat4() == d.scale);
  BOOST_CHECK(glm::mat4() == d.translation);
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_convert_transform)
{
  using matrix_pair = std::pair<glm::mat4 const, glm::mat4 const>;

#if defined(_MSC_VER) && (_MSC_VER <= 1900)
  glm::vec3::value_type const angle(float(45 _deg));
#else
  glm::vec3::value_type const angle(float(45_deg));
#endif

  glm::mat4 const ir(glm::rotate   (angle, glm::vec3(glm::gaussRand(  0.0, 20.0),
                                                     glm::gaussRand(  0.0, 20.0),
                                                     glm::gaussRand(  0.0, 20.0))));
  glm::mat4 const is(glm::scale    (       glm::vec3(glm::linearRand( 0.1, 10.0),
                                                     glm::linearRand( 0.1, 10.0),
                                                     glm::linearRand( 0.1, 10.0))));
  glm::mat4 const it(glm::translate(       glm::vec3(glm::linearRand(-1.0,  1.0),
                                                     glm::linearRand(-1.0,  1.0),
                                                     glm::linearRand(-1.0,  1.0))));

  std::array<std::pair<glm::mat4, std::string>, 7> const input_xform_list = {
    {
      std::make_pair(glm::mat4(),  "Identity"),
      std::make_pair(ir * is * it, "RST"),
      std::make_pair(ir * it * is, "RTS"),
      std::make_pair(is * ir * it, "SRT"),
      std::make_pair(is * it * ir, "STR"),
      std::make_pair(it * ir * is, "TRS"),
      std::make_pair(it * is * ir, "TSR"),
    }
  };

  std::array<std::pair<glm::decompose::order, std::string>, 6> const decompose_order_list = {
    {
      std::make_pair(glm::decompose::rst, "RST"),
      std::make_pair(glm::decompose::rts, "RTS"),
      std::make_pair(glm::decompose::srt, "SRT"),
      std::make_pair(glm::decompose::str, "STR"),
      std::make_pair(glm::decompose::trs, "TRS"),
      std::make_pair(glm::decompose::tsr, "TSR"),
    }
  };

  static float const epsilon(256 * std::numeric_limits<float>::epsilon());

  BOOST_TEST_MESSAGE("epsilon used for equality comparison to pass: " << std::fixed << epsilon);

  for (auto ix : input_xform_list) {
    for (auto e : decompose_order_list) {
      glm::mat4 r, s, t;

      glm::mat4 const   x(glm::convert::transform(ix.first, e.first, r, s, t));
      matrix_pair const p(std::make_pair(ix.first, x));

      BOOST_TEST_MESSAGE(glm::io::precision(7) << glm::io::width(1 + 1 + 1 + 7)
                         << ix.second << ':' << std::string(47 - ix.second.length(), ' ')
                         << e.second << ':' << p << '\n');

      for (unsigned i(0); i < 4; ++i) {
        for (unsigned j(0); j < 4; ++j) {
          BOOST_CHECK(std::abs(p.first[i][j] - p.second[i][j]) < epsilon);
        }
      }
    }
  }

  for (auto ix : input_xform_list) {
    for (auto e : decompose_order_list) {
      glm::mat4 const   x(glm::convert::transform(ix.first, e.first));
      matrix_pair const p(std::make_pair(ix.first, x));

      BOOST_TEST_MESSAGE(glm::io::precision(7) << glm::io::width(1 + 1 + 1 + 7)
                         << ix.second << ':' << std::string(47 - ix.second.length(), ' ')
                         << e.second << ':' << p << '\n');

      for (unsigned i(0); i < 4; ++i) {
        for (unsigned j(0); j < 4; ++j) {
          BOOST_CHECK(std::abs(p.first[i][j] - p.second[i][j]) < epsilon);
        }
      }
    }
  }
}
<commit_msg>fixed: epsilon for decomposed matrix comparison<commit_after>// -*- Mode:C++ -*-

/**************************************************************************************************/
/*                                                                                */
/* Copyright (C) 2016 University of Hull                                                          */
/*                                                                                */
/**************************************************************************************************/
/*                                                                                */
/*  module     :  glm/test/gtx_utilities.cpp                                                      */
/*  project    :                                                                                */
/*  description:                                                                                */
/*                                                                                */
/**************************************************************************************************/

// includes, system

#include <array>                 // std::array<>
#include <glm/gtc/constants.hpp> // glm::pi
#include <glm/gtc/random.hpp>    // glm::*Rand
#include <glm/gtc/vec1.hpp>      // glm::vec1
#include <glm/gtx/io.hpp>        // glm::operator<<
#include <glm/gtx/transform.hpp> // glm::rotate, glm::scale, glm::translate>

// includes, project

#include <glm/gtx/utilities.hpp>

#define HUGH_USE_TRACE
#undef HUGH_USE_TRACE
#include <hugh/support/trace.hpp>

// internal unnamed namespace

namespace {

  // types, internal (class, enum, struct, union, typedef)

  // variables, internal

  // functions, internal

} // namespace {

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/mpl/list.hpp>

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_op_literal_deg)
{
#if defined(_MSC_VER) && (_MSC_VER <= 1900)
  BOOST_CHECK(glm::pi<double>() == 180.0 _deg);

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "glm::pi<double>():" << glm::pi<double>()
                     << " =?= 180.0_deg:"    << 180.0 _deg);
#else
  BOOST_CHECK(glm::pi<double>() == 180.0_deg);

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "glm::pi<double>():" << glm::pi<double>()
                     << " =?= 180.0_deg:"    << 180.0_deg);
#endif
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_op_literal_rad)
{
#if defined(_MSC_VER) && (_MSC_VER <= 1900)
  BOOST_CHECK(glm::pi<double>() == 180.0 _deg);

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "glm::pi<double>():" << glm::pi<double>()
                     << " =?= 180.0_deg:"    << 180.0 _deg);
#else
  BOOST_CHECK(180.0_deg == glm::pi<double>());

  BOOST_TEST_MESSAGE(std::setprecision(12)
                     << "180.0_deg:"              << 180.0_deg
                     << " =?= glm::pi<double>():" << glm::pi<double>());
#endif
}

using rev_types = boost::mpl::list<glm::vec1,  glm::vec2,  glm::vec3,  glm::vec4,
                                   glm::dvec1, glm::dvec2, glm::dvec3, glm::dvec4>;

BOOST_AUTO_TEST_CASE_TEMPLATE(test_hugh_glm_gtx_utilities_rev, T, rev_types)
{
  BOOST_CHECK(glm::rev(T(glm::two_pi<typename T::value_type>())) == T(0.0));
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_sgn)
{
  BOOST_CHECK(glm::sgn(-1) < 0);
  BOOST_CHECK(glm::sgn(+1) > 0);
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_decompose)
{
  glm::mat4 const      m;
  glm::decompose const d(m);

  BOOST_CHECK(glm::mat4() == d.rotation);
  BOOST_CHECK(glm::mat4() == d.scale);
  BOOST_CHECK(glm::mat4() == d.translation);
}

BOOST_AUTO_TEST_CASE(test_hugh_glm_gtx_utilities_convert_transform)
{
  using matrix_pair = std::pair<glm::mat4 const, glm::mat4 const>;

#if defined(_MSC_VER) && (_MSC_VER <= 1900)
  glm::vec3::value_type const angle(float(45 _deg));
#else
  glm::vec3::value_type const angle(float(45_deg));
#endif

  glm::mat4 const ir(glm::rotate   (angle, glm::vec3(glm::gaussRand(  0.0, 20.0),
                                                     glm::gaussRand(  0.0, 20.0),
                                                     glm::gaussRand(  0.0, 20.0))));
  glm::mat4 const is(glm::scale    (       glm::vec3(glm::linearRand( 0.1, 10.0),
                                                     glm::linearRand( 0.1, 10.0),
                                                     glm::linearRand( 0.1, 10.0))));
  glm::mat4 const it(glm::translate(       glm::vec3(glm::linearRand(-1.0,  1.0),
                                                     glm::linearRand(-1.0,  1.0),
                                                     glm::linearRand(-1.0,  1.0))));

  std::array<std::pair<glm::mat4, std::string>, 7> const input_xform_list = {
    {
      std::make_pair(glm::mat4(),  "Identity"),
      std::make_pair(ir * is * it, "RST"),
      std::make_pair(ir * it * is, "RTS"),
      std::make_pair(is * ir * it, "SRT"),
      std::make_pair(is * it * ir, "STR"),
      std::make_pair(it * ir * is, "TRS"),
      std::make_pair(it * is * ir, "TSR"),
    }
  };

  std::array<std::pair<glm::decompose::order, std::string>, 6> const decompose_order_list = {
    {
      std::make_pair(glm::decompose::rst, "RST"),
      std::make_pair(glm::decompose::rts, "RTS"),
      std::make_pair(glm::decompose::srt, "SRT"),
      std::make_pair(glm::decompose::str, "STR"),
      std::make_pair(glm::decompose::trs, "TRS"),
      std::make_pair(glm::decompose::tsr, "TSR"),
    }
  };

  static float const epsilon(1024 * std::numeric_limits<float>::epsilon());

  BOOST_TEST_MESSAGE("epsilon used for equality comparison to pass: " << std::fixed << epsilon);

  for (auto ix : input_xform_list) {
    for (auto e : decompose_order_list) {
      glm::mat4 r, s, t;

      glm::mat4 const   x(glm::convert::transform(ix.first, e.first, r, s, t));
      matrix_pair const p(std::make_pair(ix.first, x));

      BOOST_TEST_MESSAGE(glm::io::precision(7) << glm::io::width(1 + 1 + 1 + 7)
                         << ix.second << ':' << std::string(47 - ix.second.length(), ' ')
                         << e.second << ':' << p << '\n');

      for (unsigned i(0); i < 4; ++i) {
        for (unsigned j(0); j < 4; ++j) {
          BOOST_CHECK(std::abs(p.first[i][j] - p.second[i][j]) <= epsilon);
        }
      }
    }
  }

  for (auto ix : input_xform_list) {
    for (auto e : decompose_order_list) {
      glm::mat4 const   x(glm::convert::transform(ix.first, e.first));
      matrix_pair const p(std::make_pair(ix.first, x));

      BOOST_TEST_MESSAGE(glm::io::precision(7) << glm::io::width(1 + 1 + 1 + 7)
                         << ix.second << ':' << std::string(47 - ix.second.length(), ' ')
                         << e.second << ':' << p << '\n');

      for (unsigned i(0); i < 4; ++i) {
        for (unsigned j(0); j < 4; ++j) {
          BOOST_CHECK(std::abs(p.first[i][j] - p.second[i][j]) <= epsilon);
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>/*
 * XMSS Tools
 * (C) 2017 Matthias Gierlings
 *
 * Botan is released under the Simplified BSD License (see license.txt)
 **/

#include <botan/xmss_tools.h>

namespace Botan {

#if defined(BOTAN_TARGET_OS_HAS_THREADS)

size_t XMSS_Tools::max_threads()
   {
   static const size_t threads { bench_threads() };
   return threads;
   }

size_t XMSS_Tools::bench_threads()
   {
   if(std::thread::hardware_concurrency() <= 1)
      {
      return 1;
      }
   const size_t BENCH_ITERATIONS = 1000;
   std::vector<std::thread> threads;
   threads.reserve(std::thread::hardware_concurrency());
   std::vector<std::chrono::nanoseconds> durations;

   std::vector<size_t> concurrency { std::thread::hardware_concurrency(),
                                     std::thread::hardware_concurrency() / 2 };

   for(const auto& cc : concurrency)
      {
      std::vector<XMSS_Hash> hash(std::thread::hardware_concurrency(),
                                  XMSS_Hash("SHA-256"));

      const std::vector<uint8_t> buffer(hash[0].output_length());
      std::vector<secure_vector<uint8_t>> data(
          std::thread::hardware_concurrency(),
          secure_vector<uint8_t>(hash[0].output_length()));
      auto start = std::chrono::high_resolution_clock::now();
      for(size_t i = 0; i < cc; ++i)
         {
         auto& hs = hash[i];
         auto& d = data[i];

         const size_t n_iters = BENCH_ITERATIONS * (std::thread::hardware_concurrency() / cc);
         threads.emplace_back(std::thread([n_iters, &hs, &d]()
               {
               for(size_t n = 0; n < n_iters; n++)
                  {
                  hs.h(d, d, d);
                  }
               }
            ));
         }
      durations.emplace_back(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start));
      for(auto& t : threads)
         {
         t.join();
         }
      threads.clear();
      }

      if(durations[0].count() < durations[1].count())
         {
         return concurrency[0];
         }
      else
         {
         return concurrency[1];
         }
  }

#endif

}

<commit_msg>In XMSS_Tools::bench_threads only call hardware_concurrency once<commit_after>/*
 * XMSS Tools
 * (C) 2017 Matthias Gierlings
 *
 * Botan is released under the Simplified BSD License (see license.txt)
 **/

#include <botan/xmss_tools.h>

namespace Botan {

#if defined(BOTAN_TARGET_OS_HAS_THREADS)

size_t XMSS_Tools::max_threads()
   {
   static const size_t threads { bench_threads() };
   return threads;
   }

size_t XMSS_Tools::bench_threads()
   {
   const size_t hardware_concurrency = std::thread::hardware_concurrency();

   if(hardware_concurrency <= 1)
      {
      return 1;
      }
   const size_t BENCH_ITERATIONS = 1000;
   std::vector<std::thread> threads;
   threads.reserve(hardware_concurrency);
   std::vector<std::chrono::nanoseconds> durations;

   std::vector<size_t> concurrency { hardware_concurrency,
                                     hardware_concurrency / 2 };

   for(const auto& cc : concurrency)
      {
      std::vector<XMSS_Hash> hash(hardware_concurrency,
                                  XMSS_Hash("SHA-256"));

      const std::vector<uint8_t> buffer(hash[0].output_length());
      std::vector<secure_vector<uint8_t>> data(
          hardware_concurrency,
          secure_vector<uint8_t>(hash[0].output_length()));
      auto start = std::chrono::high_resolution_clock::now();
      for(size_t i = 0; i < cc; ++i)
         {
         auto& hs = hash[i];
         auto& d = data[i];

         const size_t n_iters = BENCH_ITERATIONS * (hardware_concurrency / cc);
         threads.emplace_back(std::thread([n_iters, &hs, &d]()
               {
               for(size_t n = 0; n < n_iters; n++)
                  {
                  hs.h(d, d, d);
                  }
               }
            ));
         }
      durations.emplace_back(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now() - start));
      for(auto& t : threads)
         {
         t.join();
         }
      threads.clear();
      }

      if(durations[0].count() < durations[1].count())
         {
         return concurrency[0];
         }
      else
         {
         return concurrency[1];
         }
  }

#endif

}

<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/scan/CScanTask.cpp,v $
   $Revision: 1.45 $
   $Name:  $
   $Author: ssahle $
   $Date: 2005/02/27 20:32:01 $
   End CVS Header */

/**
 * CScanTask class.
 *
 * This class implements a scan task which is comprised of a
 * of a problem and a method.
 *
 */
#include "copasi.h"
#include "CScanTask.h"
#include "CScanProblem.h"
#include "CScanMethod.h"
#include "utilities/CReadConfig.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"

#include "model/CModel.h"
#include "model/CState.h"

#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "steadystate/CSteadyStateTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "utilities/COutputHandler.h"
#include "CopasiDataModel/CCopasiDataModel.h"

CScanTask::CScanTask(const CCopasiContainer * pParent):
    CCopasiTask(CCopasiTask::scan, pParent)
{
  mpProblem = new CScanProblem(this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::CScanTask(const CScanTask & src,
                     const CCopasiContainer * pParent):
    CCopasiTask(src, pParent)
{
  mpProblem = new CScanProblem(* (CScanProblem *) src.mpProblem, this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::~CScanTask()
{cleanup();}

void CScanTask::cleanup()
{
  //pdelete(mpProblem);
  //pdelete(mpMethod);
  //  pdelete(mpOutEnd);
  //-pdelete(mReport);
}

bool CScanTask::initialize(std::ostream * out)
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);

  bool success = true;

  if (!pProblem->getModel()->compileIfNecessary()) success = false;

  //  pdelete(mpOutEnd);
  //mpOut = & out;
  // added by Liang for Scan Report
  //mReport.open(mpOut);
  //mReport.compile();

  assert(pProblem);

  // for Steadystate Report
  //  if (pProblem->processSteadyState())
  //    pProblem->getSteadyStateTask()->initialize(mpOut);

  // for Trajectory Report
  //  if (pProblem->processTrajectory())
  //    pProblem->getTrajectoryTask()->initialize(mpOut);
  return success;
}

void CScanTask::load(CReadConfig & C_UNUSED(configBuffer))
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);
  assert(pProblem);

  //pProblem->load(configBuffer);
}

bool CScanTask::process()
{
  if (!mpProblem) fatalError();
  if (!mpMethod) fatalError();

  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();
  CScanMethod * pMethod = dynamic_cast<CScanMethod *>(mpMethod);
  if (!pMethod) fatalError();

  bool success = true;

  initSubtask();

  pMethod->setProblem(pProblem);

  //TODO: reports

  //initialize the method (parsing the ScanItems)
  if (!pMethod->init()) return false;

  //init progress bar
  mProgress = 0;
  if (mpProgressHandler) mpProgressHandler->init(pMethod->getTotalNumberOfSteps(), "performing parameter scan...", true);

  //init output handler (plotting)
  if (mpOutputHandler) mpOutputHandler->init();

  //calling the scanner, output is done in the callback
  if (!pMethod->scan()) success = false;

  //finishing progress bar and output
  if (mpProgressHandler) mpProgressHandler->finish();
  if (mpOutputHandler) mpOutputHandler->finish();

  //pProblem->initialize();

  //mReport.compile();
  //mReport.printHeader();

  /*  if ((pProblem->getSteadyStateTask() != NULL) && pProblem->processSteadyState())
      {
        pProblem->getSteadyStateTask()->getProblem()->getModel()->compileIfNecessary();
      }
    if ((pProblem->getTrajectoryTask() != NULL) && pProblem->processTrajectory())
      {
        pProblem->getTrajectoryTask()->getProblem()->getModel()->compileIfNecessary();
      }

    unsigned C_INT32 scanDimension = pProblem->getListSize();
    int i;

    // find the last master
    for (i = scanDimension - 1; i >= 0; i--)
      if (pProblem->getScanItemParameter(i, "indp")) break;

    if (i >= 0)
      // execute many simulations
      pMethod->scan(i, true, &CReport::printBody, &mReport);

    //  if (mpOutEnd)
    //    mpOutEnd->print(*Copasi->pOutputList, *mpOut);
    mReport.printFooter();

    pProblem->restore();*/
  return success;
}

bool CScanTask::processCallback()
{
  //do tasks
  mpSubtask->processForScan(!mAdjustInitialConditions, mOutputInSubtask);

  //do output
  if (mpOutputHandler && (!mOutputInSubtask)) mpOutputHandler->doOutput();

  //do progress bar
  ++mProgress;
  if (mpProgressHandler) return !mpProgressHandler->progress(mProgress);

  return true;
}

bool CScanTask::outputSeparatorCallback()
{
  if (mpOutputHandler) return mpOutputHandler->doSeparator();
  return true;
}

bool CScanTask::initSubtask()
{
  if (!mpProblem) fatalError();
  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();

  //get the parameters from the problem
  CCopasiTask::Type type = *(CCopasiTask::Type*)(pProblem->getValue("Subtask"));

  switch (type)
    {
    case CCopasiTask::steadyState:
      mpSubtask = const_cast<CCopasiTask*>
                  (dynamic_cast<const CCopasiTask*>
                   (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Steady-State"))));
      break;

    case CCopasiTask::timeCourse:
      mpSubtask = const_cast<CCopasiTask*>
                  (dynamic_cast<const CCopasiTask*>
                   (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Time-Course"))));
      break;

    default:
      mpSubtask = NULL;
    }

  /*
  if (type == CCopasiTask::steadyState)
    {
      mpSubtask=const_cast<CCopasiTask*>
                   (dynamic_cast<const CCopasiTask*>
                     (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Steady-State"))));
    }
  else
    {mpSubtask=NULL;}*/

  if (!mpSubtask) return false;

  mpSubtask->getProblem()->setModel(CCopasiDataModel::Global->getModel());
  mpSubtask->setProgressHandler(NULL);
  mpSubtask->initialize();

  mOutputInSubtask = *(bool*)(pProblem->getValue("Output in subtask"));

  mAdjustInitialConditions = *(bool*)(pProblem->getValue("Adjust initial conditions"));

  return true;
}
<commit_msg>intialize the initial state of the subtasks<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/scan/CScanTask.cpp,v $
   $Revision: 1.46 $
   $Name:  $
   $Author: ssahle $
   $Date: 2005/03/02 09:53:02 $
   End CVS Header */

/**
 * CScanTask class.
 *
 * This class implements a scan task which is comprised of a
 * of a problem and a method.
 *
 */
#include "copasi.h"
#include "CScanTask.h"
#include "CScanProblem.h"
#include "CScanMethod.h"
#include "utilities/CReadConfig.h"
#include "report/CKeyFactory.h"
#include "report/CReport.h"

#include "model/CModel.h"
#include "model/CState.h"

#include "trajectory/CTrajectoryTask.h"
#include "trajectory/CTrajectoryProblem.h"
#include "steadystate/CSteadyStateTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "utilities/COutputHandler.h"
#include "CopasiDataModel/CCopasiDataModel.h"

CScanTask::CScanTask(const CCopasiContainer * pParent):
    CCopasiTask(CCopasiTask::scan, pParent)
{
  mpProblem = new CScanProblem(this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::CScanTask(const CScanTask & src,
                     const CCopasiContainer * pParent):
    CCopasiTask(src, pParent)
{
  mpProblem = new CScanProblem(* (CScanProblem *) src.mpProblem, this);
  mpMethod = CScanMethod::createMethod();
  this->add(mpMethod, true);
  //  mpMethod->setObjectParent(this);
  ((CScanMethod *) mpMethod)->setProblem((CScanProblem *) mpProblem);
}

CScanTask::~CScanTask()
{cleanup();}

void CScanTask::cleanup()
{
  //pdelete(mpProblem);
  //pdelete(mpMethod);
  //  pdelete(mpOutEnd);
  //-pdelete(mReport);
}

bool CScanTask::initialize(std::ostream * out)
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);

  bool success = true;

  if (!pProblem->getModel()->compileIfNecessary()) success = false;

  //  pdelete(mpOutEnd);
  //mpOut = & out;
  // added by Liang for Scan Report
  //mReport.open(mpOut);
  //mReport.compile();

  assert(pProblem);

  // for Steadystate Report
  //  if (pProblem->processSteadyState())
  //    pProblem->getSteadyStateTask()->initialize(mpOut);

  // for Trajectory Report
  //  if (pProblem->processTrajectory())
  //    pProblem->getTrajectoryTask()->initialize(mpOut);
  return success;
}

void CScanTask::load(CReadConfig & C_UNUSED(configBuffer))
{
  CScanProblem* pProblem =
    dynamic_cast<CScanProblem *>(mpProblem);
  assert(pProblem);

  //pProblem->load(configBuffer);
}

bool CScanTask::process()
{
  if (!mpProblem) fatalError();
  if (!mpMethod) fatalError();

  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();
  CScanMethod * pMethod = dynamic_cast<CScanMethod *>(mpMethod);
  if (!pMethod) fatalError();

  bool success = true;

  initSubtask();

  pMethod->setProblem(pProblem);

  //TODO: reports

  //initialize the method (parsing the ScanItems)
  if (!pMethod->init()) return false;

  //init progress bar
  mProgress = 0;
  if (mpProgressHandler) mpProgressHandler->init(pMethod->getTotalNumberOfSteps(), "performing parameter scan...", true);

  //init output handler (plotting)
  if (mpOutputHandler) mpOutputHandler->init();

  //calling the scanner, output is done in the callback
  if (!pMethod->scan()) success = false;

  //finishing progress bar and output
  if (mpProgressHandler) mpProgressHandler->finish();
  if (mpOutputHandler) mpOutputHandler->finish();

  //pProblem->initialize();

  //mReport.compile();
  //mReport.printHeader();

  /*  if ((pProblem->getSteadyStateTask() != NULL) && pProblem->processSteadyState())
      {
        pProblem->getSteadyStateTask()->getProblem()->getModel()->compileIfNecessary();
      }
    if ((pProblem->getTrajectoryTask() != NULL) && pProblem->processTrajectory())
      {
        pProblem->getTrajectoryTask()->getProblem()->getModel()->compileIfNecessary();
      }

    unsigned C_INT32 scanDimension = pProblem->getListSize();
    int i;

    // find the last master
    for (i = scanDimension - 1; i >= 0; i--)
      if (pProblem->getScanItemParameter(i, "indp")) break;

    if (i >= 0)
      // execute many simulations
      pMethod->scan(i, true, &CReport::printBody, &mReport);

    //  if (mpOutEnd)
    //    mpOutEnd->print(*Copasi->pOutputList, *mpOut);
    mReport.printFooter();

    pProblem->restore();*/
  return success;
}

bool CScanTask::processCallback()
{
  //do tasks
  mpSubtask->processForScan(!mAdjustInitialConditions, mOutputInSubtask);

  //do output
  if (mpOutputHandler && (!mOutputInSubtask)) mpOutputHandler->doOutput();

  //do progress bar
  ++mProgress;
  if (mpProgressHandler) return !mpProgressHandler->progress(mProgress);

  return true;
}

bool CScanTask::outputSeparatorCallback()
{
  if (mpOutputHandler) return mpOutputHandler->doSeparator();
  return true;
}

bool CScanTask::initSubtask()
{
  if (!mpProblem) fatalError();
  CScanProblem * pProblem = dynamic_cast<CScanProblem *>(mpProblem);
  if (!pProblem) fatalError();

  //get the parameters from the problem
  CCopasiTask::Type type = *(CCopasiTask::Type*)(pProblem->getValue("Subtask"));

  CTrajectoryProblem* trajProblem;
  CSteadyStateProblem* ssProblem;
  switch (type)
    {
    case CCopasiTask::steadyState:
      mpSubtask = const_cast<CCopasiTask*>
                  (dynamic_cast<const CCopasiTask*>
                   (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Steady-State"))));
      ssProblem = dynamic_cast<CSteadyStateProblem*>(mpSubtask->getProblem());
      ssProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());
      break;

    case CCopasiTask::timeCourse:
      mpSubtask = const_cast<CCopasiTask*>
                  (dynamic_cast<const CCopasiTask*>
                   (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Time-Course"))));
      trajProblem = dynamic_cast<CTrajectoryProblem*>(mpSubtask->getProblem());
      trajProblem->setInitialState(CCopasiDataModel::Global->getModel()->getInitialState());
      break;

    default:
      mpSubtask = NULL;
    }

  /*
  if (type == CCopasiTask::steadyState)
    {
      mpSubtask=const_cast<CCopasiTask*>
                   (dynamic_cast<const CCopasiTask*>
                     (CCopasiContainer::Root->getObject(CCopasiObjectName("Task=Steady-State"))));
    }
  else
    {mpSubtask=NULL;}*/

  if (!mpSubtask) return false;

  mpSubtask->getProblem()->setModel(CCopasiDataModel::Global->getModel());
  mpSubtask->setProgressHandler(NULL);
  mpSubtask->initialize();

  mOutputInSubtask = *(bool*)(pProblem->getValue("Output in subtask"));

  mAdjustInitialConditions = *(bool*)(pProblem->getValue("Adjust initial conditions"));

  return true;
}
<|endoftext|>


<commit_before><commit_msg>Fix ROOT-7487, make TObject::Clone always proceed.<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2009-2015 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#include <votca/tools/linalg.h>
#include <boost/numeric/ublas/matrix_proxy.hpp>

#include <gsl/gsl_linalg.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_eigen.h>

namespace votca { namespace tools {

using namespace std;

void linalg_qrsolve(ub::vector<double> &x, ub::matrix<double> &A, ub::vector<double> &b, ub::vector<double> *residual)
{
    // check matrix for zero column
    int nonzero_found = 0;
    for(size_t j=0; j<A.size2(); j++) {
        nonzero_found = 0;
        for(size_t i=0; i<A.size1(); i++) {
            if(fabs(A(i,j))>0) {
                nonzero_found = 1;
            }
        }
        if(nonzero_found==0) {
            throw "qrsolve_zero_column_in_matrix";
        }
    }

    gsl_matrix_view m
        = gsl_matrix_view_array (&A(0,0), A.size1(), A.size2());

    gsl_vector_view gb
        = gsl_vector_view_array (&b(0), b.size());

    gsl_vector *gsl_x = gsl_vector_alloc (x.size());
    gsl_vector *tau = gsl_vector_alloc (x.size());
    gsl_vector *gsl_residual = gsl_vector_alloc (b.size());

    gsl_linalg_QR_decomp (&m.matrix, tau);

    gsl_linalg_QR_lssolve (&m.matrix, tau, &gb.vector, gsl_x, gsl_residual);

    for (size_t i =0 ; i < x.size(); i++)
        x(i) = gsl_vector_get(gsl_x, i);

    if(residual)
        for (size_t i =0 ; i < residual->size(); i++)
            (*residual)(i) = gsl_vector_get(gsl_residual, i);

    gsl_vector_free (gsl_x);
    gsl_vector_free (tau);
    gsl_vector_free (gsl_residual);
}

void linalg_constrained_qrsolve(ub::vector<double> &x, ub::matrix<double> &A, ub::vector<double> &b, ub::matrix<double> &constr)
{
    // check matrix for zero column
    int nonzero_found = 0;
    for(size_t j=0; j<A.size2(); j++) {
        nonzero_found = 0;
        for(size_t i=0; i<A.size1(); i++) {
            if(fabs(A(i,j))>0) {
                nonzero_found = 1;
            }
        }
        if(nonzero_found==0) {
            throw std::runtime_error("constrained_qrsolve_zero_column_in_matrix");
        }
    }

    // Transpose constr:
    constr = trans(constr);

    const int N = b.size();
    const int ngrid = x.size()/2;

    // temporary variables
    ub::matrix<double> Q(2*ngrid, 2*ngrid);       // Q matrix: QR decomposition of trans(B)
    ub::matrix<double> Q_k(2*ngrid, 2*ngrid);
    ub::identity_matrix<double> I (2*ngrid);
    ub::vector<double> v(2*ngrid);

    Q = ub::zero_matrix<double>(2*ngrid, 2*ngrid);
    Q_k = ub::zero_matrix<double>(2*ngrid, 2*ngrid);
    v = ub::zero_vector<double>(2*ngrid);

    double *tmp = & constr(0,0);
    gsl_matrix_view gsl_constr
      = gsl_matrix_view_array (tmp, constr.size1(), constr.size2());

    tmp = &b(0);
    gsl_vector_view gsl_b
         = gsl_vector_view_array (tmp, b.size());

    gsl_vector *tau_qr = gsl_vector_alloc (ngrid);

    gsl_linalg_QR_decomp (&gsl_constr.matrix, tau_qr);

    Q = I;

    for (int k = ngrid; k > 0 ; k--) {

        for (int icout = 0; icout < k - 1; icout++) {
             v(icout) = 0;
        }
        v(k - 1) = 1.0;

        for (int icout = k; icout < 2*ngrid; icout++) {
             v(icout) = gsl_matrix_get(&gsl_constr.matrix, icout, k - 1 );
        }

        Q_k = I - gsl_vector_get(tau_qr, k - 1 ) * outer_prod ( v, v );
        Q = prec_prod(Q, Q_k);

    }

    Q = trans(Q);
    gsl_vector_free (tau_qr);

    // Calculate A * Q and store the result in A
    A = prec_prod(A, Q);

    // A = [A1 A2], so A2 is just a block of A
    ub::matrix<double> A2 = ub::matrix_range<ub::matrix<double> >(A,
            ub::range (0, N), ub::range (ngrid, 2*ngrid)
         );

    tmp = &A2(0,0);
    gsl_matrix_view gsl_A2
         = gsl_matrix_view_array (tmp, A2.size1(), A2.size2());

    gsl_vector *z = gsl_vector_alloc (ngrid);
    gsl_vector *tau_solve = gsl_vector_alloc (ngrid);  // already done!
    gsl_vector *residual = gsl_vector_alloc (N);

    gsl_linalg_QR_decomp (&gsl_A2.matrix, tau_solve);
    gsl_linalg_QR_lssolve (&gsl_A2.matrix, tau_solve, &gsl_b.vector, z, residual);

    // Next two cycles assemble vector from y (which is zero-vector) and z
    // (which we just got by gsl_linalg_QR_lssolve)

    for (int i = 0; i < ngrid; i++ ) {
           x[i] = 0.0;
    }

    for (int i = ngrid; i < 2 * ngrid; i++ ) {
           x[i] = gsl_vector_get(z, i - ngrid);
    }

    // To get the final answer this vector should be multiplied by matrix Q
    // TODO: here i changed the sign, check again! (victor)
    x = -prec_prod( Q, x );

    gsl_vector_free (z);
    gsl_vector_free (tau_solve);
    gsl_vector_free (residual);
}

}}
<commit_msg>constrained_qrsolve for arbitrary constraints<commit_after>/*
 * Copyright 2009-2015 The VOTCA Development Team (http://www.votca.org)
 *
 * 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.
 *
 */

#include <votca/tools/linalg.h>
#include <boost/numeric/ublas/matrix_proxy.hpp>

#include <gsl/gsl_linalg.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_eigen.h>

namespace votca { namespace tools {

using namespace std;

void linalg_qrsolve(ub::vector<double> &x, ub::matrix<double> &A, ub::vector<double> &b, ub::vector<double> *residual)
{
    // check matrix for zero column
    int nonzero_found = 0;
    for(size_t j=0; j<A.size2(); j++) {
        nonzero_found = 0;
        for(size_t i=0; i<A.size1(); i++) {
            if(fabs(A(i,j))>0) {
                nonzero_found = 1;
            }
        }
        if(nonzero_found==0) {
            throw "qrsolve_zero_column_in_matrix";
        }
    }

    gsl_matrix_view m
        = gsl_matrix_view_array (&A(0,0), A.size1(), A.size2());

    gsl_vector_view gb
        = gsl_vector_view_array (&b(0), b.size());

    gsl_vector *gsl_x = gsl_vector_alloc (x.size());
    gsl_vector *tau = gsl_vector_alloc (x.size());
    gsl_vector *gsl_residual = gsl_vector_alloc (b.size());

    gsl_linalg_QR_decomp (&m.matrix, tau);

    gsl_linalg_QR_lssolve (&m.matrix, tau, &gb.vector, gsl_x, gsl_residual);

    for (size_t i =0 ; i < x.size(); i++)
        x(i) = gsl_vector_get(gsl_x, i);

    if(residual)
        for (size_t i =0 ; i < residual->size(); i++)
            (*residual)(i) = gsl_vector_get(gsl_residual, i);

    gsl_vector_free (gsl_x);
    gsl_vector_free (tau);
    gsl_vector_free (gsl_residual);
}

void linalg_constrained_qrsolve(ub::vector<double> &x, ub::matrix<double> &A, ub::vector<double> &b, ub::matrix<double> &constr)
{
    // check matrix for zero column
    int nonzero_found = 0;
    for(size_t j=0; j<A.size2(); j++) {
        nonzero_found = 0;
        for(size_t i=0; i<A.size1(); i++) {
            if(fabs(A(i,j))>0) {
                nonzero_found = 1;
            }
        }
        if(nonzero_found==0) {
            throw std::runtime_error("constrained_qrsolve_zero_column_in_matrix");
        }
    }

    const int N = b.size();
    const int ngrid = x.size()/2;
    const int ysize = constr.size1(); //number of constraints is number of rows of constr
    //std::cout << "ysize: " << ysize << std::endl;

    //std::cout << "constr^T.size1: " << constr.size1() << " , constr^T.size2: " << constr.size2() << std::endl;

    // Transpose constr:
    constr = trans(constr);

    // temporary variables
    ub::matrix<double> Q(2*ngrid, 2*ngrid);
    // Q matrix: QR decomposition of trans(B) (trans(B) has 2*ngrid rows and ysize columns )
    // Q matrix is orthogonal 2*ngrid x 2*ngrid matrix
    ub::matrix<double> Q_k(2*ngrid, 2*ngrid);
    ub::identity_matrix<double> I (2*ngrid);
    ub::vector<double> v(2*ngrid);

    Q = ub::zero_matrix<double>(2*ngrid, 2*ngrid);
    Q_k = ub::zero_matrix<double>(2*ngrid, 2*ngrid);
    v = ub::zero_vector<double>(2*ngrid);

    double *tmp = & constr(0,0);
    gsl_matrix_view gsl_constr
      = gsl_matrix_view_array (tmp, constr.size1(), constr.size2());

    tmp = &b(0);
    gsl_vector_view gsl_b
         = gsl_vector_view_array (tmp, b.size());

    //vector to store Householder coefficients of QR-decomposition of trans(B)
    gsl_vector *tau_qr = gsl_vector_alloc (ysize);

    gsl_linalg_QR_decomp (&gsl_constr.matrix, tau_qr);

    //construct the matrix Q of trans(B)=Q * R
    Q = I;

    //k=1,..,ysize (number of rows of B, meaning number of constraints)
    for (int k = ysize; k > 0 ; k--) {

        for (int icout = 0; icout < k - 1; icout++) {
             v(icout) = 0;
        }
        v(k - 1) = 1.0;

        for (int icout = k; icout < 2*ngrid; icout++) {
             v(icout) = gsl_matrix_get(&gsl_constr.matrix, icout, k - 1 );
        }

        Q_k = I - gsl_vector_get(tau_qr, k - 1 ) * outer_prod ( v, v );
        Q = prec_prod(Q, Q_k);

    }

    //now Q is the one of trans(B)=Q * R
    Q = trans(Q);
    gsl_vector_free (tau_qr);

    // Calculate A * Q and store the result in A
    A = prec_prod(A, Q);

    // A = [A1 A2], so A2 is just a block of A
    // [A1 A2] has N rows. A1 has ysize columns (range(0,ysize) ).
    //A2 has 2*ngrid-ysize columns ( range(ysize,2*ngrid) ).
    ub::matrix<double> A2 = ub::matrix_range<ub::matrix<double> >(A,
            ub::range (0, N), ub::range (ysize, 2*ngrid)
         );

    tmp = &A2(0,0);
    gsl_matrix_view gsl_A2
         = gsl_matrix_view_array (tmp, A2.size1(), A2.size2());

    //now perform QR-decomposition of A2 to solve the least-squares problem A2 * z = b
    //A2 has N rows and (2*ngrid-ysize) columns ->
    gsl_vector *z = gsl_vector_alloc (2*ngrid-ysize);
    gsl_vector *tau_solve = gsl_vector_alloc (2*ngrid-ysize);
    gsl_vector *residual = gsl_vector_alloc (N);

    gsl_linalg_QR_decomp (&gsl_A2.matrix, tau_solve);
    gsl_linalg_QR_lssolve (&gsl_A2.matrix, tau_solve, &gsl_b.vector, z, residual);

    // Next two cycles assemble vector from y (which is zero-vector) and z
    // (which we just got by gsl_linalg_QR_lssolve)

    //vector y has ysize components
    for (int i = 0; i < ysize; i++ ) {
           x[i] = 0.0;
    }

    //vector z has (2*ngrid-ysize) components
    for (int i = ysize; i < 2 * ngrid; i++ ) {
           x[i] = gsl_vector_get(z, i - ysize);
    }

    /*for (int i = 0; i < 2 * ngrid; i++ ) {
        std::cout << "x[" << i << "]: " << x[i] << std::endl;
    }*/

    // To get the final answer this vector should be multiplied by matrix Q
    // TODO: here i changed the sign, check again! (victor)
    x = -prec_prod( Q, x );

    /*for (int i = 0; i < 2 * ngrid; i++ ) {
        std::cout << "x[" << i << "]: " << x[i] << std::endl;
    }*/

    gsl_vector_free (z);
    gsl_vector_free (tau_solve);
    gsl_vector_free (residual);
}

/*void linalg_constrained_qrsolve(ub::vector<double> &x, ub::matrix<double> &A, ub::vector<double> &b, ub::matrix<double> &constr)
{
    // check matrix for zero column
    int nonzero_found = 0;
    for(size_t j=0; j<A.size2(); j++) {
        nonzero_found = 0;
        for(size_t i=0; i<A.size1(); i++) {
            if(fabs(A(i,j))>0) {
                nonzero_found = 1;
            }
        }
        if(nonzero_found==0) {
            throw std::runtime_error("constrained_qrsolve_zero_column_in_matrix");
        }
    }

    // Transpose constr:
    constr = trans(constr);

    const int N = b.size();
    const int ngrid = x.size()/2;

    // temporary variables
    ub::matrix<double> Q(2*ngrid, 2*ngrid);       // Q matrix: QR decomposition of trans(B)
    ub::matrix<double> Q_k(2*ngrid, 2*ngrid);
    ub::identity_matrix<double> I (2*ngrid);
    ub::vector<double> v(2*ngrid);

    Q = ub::zero_matrix<double>(2*ngrid, 2*ngrid);
    Q_k = ub::zero_matrix<double>(2*ngrid, 2*ngrid);
    v = ub::zero_vector<double>(2*ngrid);

    double *tmp = & constr(0,0);
    gsl_matrix_view gsl_constr
      = gsl_matrix_view_array (tmp, constr.size1(), constr.size2());

    tmp = &b(0);
    gsl_vector_view gsl_b
         = gsl_vector_view_array (tmp, b.size());

    gsl_vector *tau_qr = gsl_vector_alloc (ngrid);

    gsl_linalg_QR_decomp (&gsl_constr.matrix, tau_qr);

    Q = I;

    for (int k = ngrid; k > 0 ; k--) {

        for (int icout = 0; icout < k - 1; icout++) {
             v(icout) = 0;
        }
        v(k - 1) = 1.0;

        for (int icout = k; icout < 2*ngrid; icout++) {
             v(icout) = gsl_matrix_get(&gsl_constr.matrix, icout, k - 1 );
        }

        Q_k = I - gsl_vector_get(tau_qr, k - 1 ) * outer_prod ( v, v );
        Q = prec_prod(Q, Q_k);

    }

    Q = trans(Q);
    gsl_vector_free (tau_qr);

    // Calculate A * Q and store the result in A
    A = prec_prod(A, Q);

    // A = [A1 A2], so A2 is just a block of A
    ub::matrix<double> A2 = ub::matrix_range<ub::matrix<double> >(A,
            ub::range (0, N), ub::range (ngrid, 2*ngrid)
         );

    tmp = &A2(0,0);
    gsl_matrix_view gsl_A2
         = gsl_matrix_view_array (tmp, A2.size1(), A2.size2());

    gsl_vector *z = gsl_vector_alloc (ngrid);
    gsl_vector *tau_solve = gsl_vector_alloc (ngrid);  // already done!
    gsl_vector *residual = gsl_vector_alloc (N);

    gsl_linalg_QR_decomp (&gsl_A2.matrix, tau_solve);
    gsl_linalg_QR_lssolve (&gsl_A2.matrix, tau_solve, &gsl_b.vector, z, residual);

    // Next two cycles assemble vector from y (which is zero-vector) and z
    // (which we just got by gsl_linalg_QR_lssolve)

    for (int i = 0; i < ngrid; i++ ) {
           x[i] = 0.0;
    }

    for (int i = ngrid; i < 2 * ngrid; i++ ) {
           x[i] = gsl_vector_get(z, i - ngrid);
    }

    // To get the final answer this vector should be multiplied by matrix Q
    // TODO: here i changed the sign, check again! (victor)
    x = -prec_prod( Q, x );

    gsl_vector_free (z);
    gsl_vector_free (tau_solve);
    gsl_vector_free (residual);
}*/

}}<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium 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 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <vector>
#include <iostream>

#include <jitk/fuser_cache.hpp>

using namespace std;

namespace bohrium {
namespace jitk {

namespace {

// Handling view IDs
class ViewDB {
private:
    size_t maxid;
    std::map<bh_view,size_t> _map;
public:
    ViewDB() : maxid(0) {}

    // Insert an object
    std::pair<size_t,bool> insert(const bh_view &v) {
        auto it = _map.find(v);
        if (it == _map.end()) {
            size_t id = maxid++;
            _map.insert(std::make_pair(v,id));
            return std::make_pair(id,true);

        } else {
            return  std::make_pair(it->second,false);
        }
    }
};

constexpr size_t SEP_INSTR = SIZE_MAX;
constexpr size_t SEP_OP = SIZE_MAX - 1;
constexpr size_t SEP_SHAPE = SIZE_MAX - 2;
constexpr size_t SEP_CONSTANT = SIZE_MAX - 3;

/* The Instruction hash consists of the following fields:
 * <view_id><start><ndim>[<shape><stride><SEP_SHAPE>...]<SEP_OP>
 */
void hash_view(const bh_view &view, ViewDB &views, std::stringstream &ss) {
    if (not bh_is_constant(&view)) {
        size_t view_id = views.insert(view).first;
        ss << view_id;
        // Sliding views has identical hashes across iterations
        if (view.slide.empty()) {
            ss << view.start;
        }

        ss << view.ndim;
        for (int j = 0; j < view.ndim; ++j) {
            ss << view.shape[j];
            ss << view.stride[j];
            ss << SEP_SHAPE;
        }
        ss << SEP_OP;
    } else {
        // Notice, we can ignore the value of the constant but we need to hash the location of the constant
        ss << SEP_CONSTANT;
    }
}

/* The Instruction hash consists of the following fields:
 * <opcode[<hash_view>...]<sweep_axis()><SEP_INSTR>
 */
void hash_instr(const bh_instruction &instr, ViewDB &views, std::stringstream &ss) {
    ss << instr.opcode; // <opcode>
    for(const bh_view &op: instr.operand) {
        hash_view(op, views, ss);
    }
    ss << instr.sweep_axis();
    ss << SEP_INSTR;
}

// Hash of an instruction list
size_t hash_instr_list(const vector<bh_instruction *> &instr_list) {
    stringstream ss;
    ViewDB views;
    for (const bh_instruction *instr: instr_list) {
        hash_instr(*instr, views, ss);
    }
    return util::hash(ss.str());
}

// Replace the cached values of constants and bases arrays in `instr` with their original values
void update_with_origin(bh_instruction &instr, const bh_instruction *origin,
                        const std::map<bh_base*, bh_base*> &base_cached2new) {
    assert(instr.origin_id == origin->origin_id);
    assert(instr.opcode == origin->opcode);
    for (size_t i = 0; i < instr.operand.size(); ++i) {
        if (not instr.operand[i].slide.empty()) {
            instr.operand[i].start = origin->operand[i].start;
        }

        if (bh_is_constant(&instr.operand[i])) {
            // NB: sweeped axis values shouldn't be updated
            if (not bh_opcode_is_sweep(instr.opcode)) {
                instr.constant = origin->constant;
            }
        } else {
            instr.operand[i].base = base_cached2new.at(instr.operand[i].base);
            assert(instr.operand[i].base == origin->operand[i].base);
        }
    }
}

// Replace the cached values of constants and bases arrays in `block` with their original values
void update_with_origin(Block &block, const std::map<bh_base*, bh_base*> &base_cached2new,
                        const map<int64_t, const bh_instruction *> &origin_id_to_instr) {
    if (block.isInstr()) {
        assert(block.getInstr()->origin_id >= 0);
        bh_instruction instr(*block.getInstr());
        update_with_origin(instr, origin_id_to_instr.at(instr.origin_id), base_cached2new);
        block.setInstr(instr);
    } else {
        LoopB &loop = block.getLoop();
        for (Block &b: loop._block_list) {
            update_with_origin(b, base_cached2new, origin_id_to_instr);
        }
        set<bh_base*> frees;
        for (bh_base *b: loop._frees) {
            frees.insert(base_cached2new.at(b));
        }
        loop._frees = std::move(frees);
        loop.metadataUpdate();
    }
}

// We assign the base IDs in the order they appear in the 'instr_list'
// Notice, the base IDs corresponds to their position in the returned vector
std::vector<bh_base*> calc_base_ids(const vector<bh_instruction *> &instr_list) {
    std::vector<bh_base*> ret;
    std::set<bh_base*> unique_bases;
    for (const auto &instr: instr_list) {
        for (const bh_view *view: instr->get_views()) {
            if (not util::exist(unique_bases, view->base)) {
                unique_bases.insert(view->base);
                ret.push_back(view->base);
            }
        }
    }
    return ret;
}
} // Anon namespace

pair<vector<Block>, bool> FuseCache::get(const vector<bh_instruction *> &instr_list) {
    const size_t lookup_hash = hash_instr_list(instr_list);
    ++stat.fuser_cache_lookups;

    if (_cache.find(lookup_hash) != _cache.end()) { // Cache hit!
        // Create a map: 'origin_id' => instruction for updating the constants
        map<int64_t, const bh_instruction *> origin_id_to_instr;
        for(const bh_instruction *instr: instr_list) {
            assert(instr->origin_id >= 0);
            assert(not util::exist(origin_id_to_instr, instr->origin_id));
            origin_id_to_instr.insert(make_pair(instr->origin_id, instr));
        }
        // Create a map: 'cached bases' => 'new bases' for updating the base arrays
        const CachePayload &cached = _cache.at(lookup_hash);
        std::map<bh_base*, bh_base*> base_cached2new;
        {
            size_t id = 0;
            for(auto &base: calc_base_ids(instr_list)) {
                assert(id < cached.base_ids.size());
                base_cached2new[cached.base_ids[id++]] = base;
            }
        }
        // Let's make a copy of the cached block list and update the bases
        vector<Block> ret = cached.block_list;
        for(Block &block: ret) {
            update_with_origin(block, base_cached2new, origin_id_to_instr);
        }
        return make_pair(std::move(ret), true);
    } else { // Cache miss!
        ++stat.fuser_cache_misses;
        return make_pair(vector<Block>(), false);
    }
}

void FuseCache::insert(const vector<bh_instruction *> &instr_list, vector<Block> block_list) {
    const size_t lookup_hash = hash_instr_list(instr_list);
    CachePayload payload = {std::move(block_list), calc_base_ids(instr_list)};
    _cache.insert(make_pair(lookup_hash, std::move(payload)));
}

} // jitk
} // bohrium
<commit_msg>Added a special case with dynamic views with shape 1 in all dimensions<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium 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 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <vector>
#include <iostream>

#include <jitk/fuser_cache.hpp>

using namespace std;

namespace bohrium {
namespace jitk {

namespace {

// Handling view IDs
class ViewDB {
private:
    size_t maxid;
    std::map<bh_view,size_t> _map;
public:
    ViewDB() : maxid(0) {}

    // Insert an object
    std::pair<size_t,bool> insert(const bh_view &v) {
        auto it = _map.find(v);
        if (it == _map.end()) {
            size_t id = maxid++;
            _map.insert(std::make_pair(v,id));
            return std::make_pair(id,true);

        } else {
            return  std::make_pair(it->second,false);
        }
    }
};

constexpr size_t SEP_INSTR = SIZE_MAX;
constexpr size_t SEP_OP = SIZE_MAX - 1;
constexpr size_t SEP_SHAPE = SIZE_MAX - 2;
constexpr size_t SEP_CONSTANT = SIZE_MAX - 3;

/* The Instruction hash consists of the following fields:
 * <view_id><start><ndim>[<shape><stride><SEP_SHAPE>...]<SEP_OP>
 */
void hash_view(const bh_view &view, ViewDB &views, std::stringstream &ss) {
    if (not bh_is_constant(&view)) {
        size_t view_id = views.insert(view).first;
        ss << view_id;
        // Sliding views has identical hashes across iterations
        if (view.slide.empty()) {
            ss << view.start;
        } else {
            // Check whether the shape of the sliding view is a single value
            bool single_index = true;
            for (int i = 0; i < view.ndim; i++) {
                if (view.shape[i] != 1) {
                    single_index = false;
                    break;
                }
            }
            if (!single_index) {
                ss << view.start;
            }
        }

        ss << view.ndim;
        for (int j = 0; j < view.ndim; ++j) {
            ss << view.shape[j];
            ss << view.stride[j];
            ss << SEP_SHAPE;
        }
        ss << SEP_OP;
    } else {
        // Notice, we can ignore the value of the constant but we need to hash the location of the constant
        ss << SEP_CONSTANT;
    }
}

/* The Instruction hash consists of the following fields:
 * <opcode[<hash_view>...]<sweep_axis()><SEP_INSTR>
 */
void hash_instr(const bh_instruction &instr, ViewDB &views, std::stringstream &ss) {
    ss << instr.opcode; // <opcode>
    for(const bh_view &op: instr.operand) {
        hash_view(op, views, ss);
    }
    ss << instr.sweep_axis();
    ss << SEP_INSTR;
}

// Hash of an instruction list
size_t hash_instr_list(const vector<bh_instruction *> &instr_list) {
    stringstream ss;
    ViewDB views;
    for (const bh_instruction *instr: instr_list) {
        hash_instr(*instr, views, ss);
    }
    return util::hash(ss.str());
}

// Replace the cached values of constants and bases arrays in `instr` with their original values
void update_with_origin(bh_instruction &instr, const bh_instruction *origin,
                        const std::map<bh_base*, bh_base*> &base_cached2new) {
    assert(instr.origin_id == origin->origin_id);
    assert(instr.opcode == origin->opcode);
    for (size_t i = 0; i < instr.operand.size(); ++i) {
        if (not instr.operand[i].slide.empty()) {
            instr.operand[i].start = origin->operand[i].start;
        }

        if (bh_is_constant(&instr.operand[i])) {
            // NB: sweeped axis values shouldn't be updated
            if (not bh_opcode_is_sweep(instr.opcode)) {
                instr.constant = origin->constant;
            }
        } else {
            instr.operand[i].base = base_cached2new.at(instr.operand[i].base);
            assert(instr.operand[i].base == origin->operand[i].base);
        }
    }
}

// Replace the cached values of constants and bases arrays in `block` with their original values
void update_with_origin(Block &block, const std::map<bh_base*, bh_base*> &base_cached2new,
                        const map<int64_t, const bh_instruction *> &origin_id_to_instr) {
    if (block.isInstr()) {
        assert(block.getInstr()->origin_id >= 0);
        bh_instruction instr(*block.getInstr());
        update_with_origin(instr, origin_id_to_instr.at(instr.origin_id), base_cached2new);
        block.setInstr(instr);
    } else {
        LoopB &loop = block.getLoop();
        for (Block &b: loop._block_list) {
            update_with_origin(b, base_cached2new, origin_id_to_instr);
        }
        set<bh_base*> frees;
        for (bh_base *b: loop._frees) {
            frees.insert(base_cached2new.at(b));
        }
        loop._frees = std::move(frees);
        loop.metadataUpdate();
    }
}

// We assign the base IDs in the order they appear in the 'instr_list'
// Notice, the base IDs corresponds to their position in the returned vector
std::vector<bh_base*> calc_base_ids(const vector<bh_instruction *> &instr_list) {
    std::vector<bh_base*> ret;
    std::set<bh_base*> unique_bases;
    for (const auto &instr: instr_list) {
        for (const bh_view *view: instr->get_views()) {
            if (not util::exist(unique_bases, view->base)) {
                unique_bases.insert(view->base);
                ret.push_back(view->base);
            }
        }
    }
    return ret;
}
} // Anon namespace

pair<vector<Block>, bool> FuseCache::get(const vector<bh_instruction *> &instr_list) {
    const size_t lookup_hash = hash_instr_list(instr_list);
    ++stat.fuser_cache_lookups;

    if (_cache.find(lookup_hash) != _cache.end()) { // Cache hit!
        // Create a map: 'origin_id' => instruction for updating the constants
        map<int64_t, const bh_instruction *> origin_id_to_instr;
        for(const bh_instruction *instr: instr_list) {
            assert(instr->origin_id >= 0);
            assert(not util::exist(origin_id_to_instr, instr->origin_id));
            origin_id_to_instr.insert(make_pair(instr->origin_id, instr));
        }
        // Create a map: 'cached bases' => 'new bases' for updating the base arrays
        const CachePayload &cached = _cache.at(lookup_hash);
        std::map<bh_base*, bh_base*> base_cached2new;
        {
            size_t id = 0;
            for(auto &base: calc_base_ids(instr_list)) {
                assert(id < cached.base_ids.size());
                base_cached2new[cached.base_ids[id++]] = base;
            }
        }
        // Let's make a copy of the cached block list and update the bases
        vector<Block> ret = cached.block_list;
        for(Block &block: ret) {
            update_with_origin(block, base_cached2new, origin_id_to_instr);
        }
        return make_pair(std::move(ret), true);
    } else { // Cache miss!
        ++stat.fuser_cache_misses;
        return make_pair(vector<Block>(), false);
    }
}

void FuseCache::insert(const vector<bh_instruction *> &instr_list, vector<Block> block_list) {
    const size_t lookup_hash = hash_instr_list(instr_list);
    CachePayload payload = {std::move(block_list), calc_base_ids(instr_list)};
    _cache.insert(make_pair(lookup_hash, std::move(payload)));
}

} // jitk
} // bohrium
<|endoftext|>