<commit_before>/*
 * HQMenuComponent.cpp
 *
 *  Created on: Oct 25, 2012
 *      Author: root
 */
#include "HQMenuComponent.h"
#include "server/zone/Zone.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/scene/components/ObjectMenuComponent.h"
#include "server/zone/packets/object/ObjectMenuResponse.h"

#include "server/zone/objects/scene/SceneObjectType.h"
#include "server/zone/objects/scene/SceneObject.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/player/FactionStatus.h"
#include "server/zone/objects/structure/StructureObject.h"

#include "server/zone/objects/building/components/DestructibleBuildingDataComponent.h"
#include "server/zone/objects/building/BuildingObject.h"
#include "server/chat/StringIdChatParameter.h"

#include "server/zone/objects/player/sui/messagebox/SuiMessageBox.h"
#include "server/zone/objects/player/sui/transferbox/SuiTransferBox.h"
#include "server/zone/objects/player/sui/inputbox/SuiInputBox.h"

#include "server/zone/managers/gcw/GCWManager.h"

void HQMenuComponent::fillObjectMenuResponse(SceneObject* sceneObject, ObjectMenuResponse* menuResponse, CreatureObject* player) {
	ManagedReference<BuildingObject*> building = cast<BuildingObject*>(sceneObject->getParentRecursively(SceneObjectType::FACTIONBUILDING).get().get());

	if (building == NULL)
			return;

	Zone* zone = building->getZone();

	if(zone == NULL)
		return;

	GCWManager* gcwMan = zone->getGCWManager();

	ManagedReference<PlayerObject*> playerObject = player->getPlayerObject();
	if(playerObject == NULL)
		return;

	if(building->getFaction() == player->getFaction()) {

		menuResponse->addRadialMenuItem(228, 3, "@hq:mnu_defense_status");

		if(gcwMan->isShutdownSequenceStarted(building)){
			menuResponse->addRadialMenuItem(231, 3, "@hq:mnu_shutdown");  // Shutdown facility
		}

		// donate menus removed
		menuResponse->addRadialMenuItem(37, 3, "@hq:mnu_donate"); // Donate
		//menuResponse->addRadialMenuItemToRadialID(37, 225, 3,  "@hq:mnu_donate_money"); // Donate MOney
		menuResponse->addRadialMenuItemToRadialID(37, 226, 3, "@hq:mnu_donate_deed"); // donate defense
		//menuResponse->addRadialMenuItemToRadialID(37, 227, 3, "@hq:mnu_donate_resource"); // donate resource

		if(building->getOwnerCreatureObject() == player){
			menuResponse->addRadialMenuItem(38, 3, "@hq:mnu_reset_vulnerability"); // Reset Vulnerability
		}

	} else {

		if(playerObject->getFactionStatus() == FactionStatus::OVERT) {

			//menuResponse->addRadialMenuItem(228, 3, "@hq:mnu_defense_status");

			if(gcwMan->isPowerOverloaded(building) && !gcwMan->isShutdownSequenceStarted(building)){
				menuResponse->addRadialMenuItem(230, 3, "@hq:mnu_overload");  // activate overload
			}
		}
	}

	//if(true){

	// Admin menus to test out vulnerability manually
	/*
	if ( player->getPlayerObject()->isPrivileged()) {
		//info("player is privelaged", true);
		menuResponse->addRadialMenuItem(35, 3, "PVP EVENT");
		menuResponse->addRadialMenuItemToRadialID(35, MAKEIMPERIAL, 3, "MAKE VULNERABLE");
		menuResponse->addRadialMenuItemToRadialID(35, MAKENEUTRAL, 3, "MAKE INVULNERABLE");

	}
	*/

	//menuResponse->addRadialMenuItem(229, 3, "@player_structure:permission_destroy"); //Destroy Structure

}

int HQMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* creature, byte selectedID) {
	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();
	if (ghost == NULL)
		return 1;

	ManagedReference<BuildingObject*> building = cast<BuildingObject*>(sceneObject->getParentRecursively(SceneObjectType::FACTIONBUILDING).get().get());
	if(building == NULL)
		return 1;

	DestructibleBuildingDataComponent* baseData = getDestructibleBuildingDataComponent(building);

	if(baseData == NULL)
		return 1;

	Zone* zone = building->getZone();

	if(zone == NULL)
		return 1;

	ManagedReference<GCWManager*> gcwMan = zone->getGCWManager();

	if(gcwMan == NULL)
		return 1;

	if (selectedID == 20){
		gcwMan->sendStatus(building,creature);
	}
	else if( selectedID == 228 || selectedID == 20){

		if(ghost->getFactionStatus() != FactionStatus::OVERT && creature->getFaction() != building->getFaction()){
				creature->sendSystemMessage("@faction/faction_hq/faction_hq_response:declared_personnel_only"); // Only Special Forces personnel may access this terminal
				return 1;
		}

		gcwMan->sendBaseDefenseStatus(creature, building);
	} else if ( selectedID == 38) {
		gcwMan->sendResetVerification(creature, building);
	} else if ( selectedID == 229) {
		//info("Destroy base here",true);
		gcwMan->doBaseDestruction(building);
	} else if ( selectedID == 230 ) {
		creature->sendSystemMessage("BASE WILL BE DESTROYED UNLESS IT IS STOPPED");

		gcwMan->scheduleBaseDestruction(building);
	} else if (selectedID == 231) {
		//info("abort shutdown",true);
		gcwMan->abortShutdownSequence(creature,building);

	} else if (selectedID == 226){
		gcwMan->sendSelectDeedToDonate(building,creature,0);
	}
	return 0;
}

DestructibleBuildingDataComponent* HQMenuComponent::getDestructibleBuildingDataComponent(BuildingObject* building){
	DestructibleBuildingDataComponent* baseData = NULL;

	if (building != NULL){
		if(building->isGCWBase()){
			DataObjectComponentReference* data = building->getDataObjectComponent();

			if(data != NULL)
				baseData = cast<DestructibleBuildingDataComponent*>(data->get());

		}
	}

		return baseData;
}
<commit_msg>(unstable) [fixed] Opposite faction players can no longer view base vulnerability times.<commit_after>/*
 * HQMenuComponent.cpp
 *
 *  Created on: Oct 25, 2012
 *      Author: root
 */
#include "HQMenuComponent.h"
#include "server/zone/Zone.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/scene/components/ObjectMenuComponent.h"
#include "server/zone/packets/object/ObjectMenuResponse.h"

#include "server/zone/objects/scene/SceneObjectType.h"
#include "server/zone/objects/scene/SceneObject.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/player/FactionStatus.h"
#include "server/zone/objects/structure/StructureObject.h"

#include "server/zone/objects/building/components/DestructibleBuildingDataComponent.h"
#include "server/zone/objects/building/BuildingObject.h"
#include "server/chat/StringIdChatParameter.h"

#include "server/zone/objects/player/sui/messagebox/SuiMessageBox.h"
#include "server/zone/objects/player/sui/transferbox/SuiTransferBox.h"
#include "server/zone/objects/player/sui/inputbox/SuiInputBox.h"

#include "server/zone/managers/gcw/GCWManager.h"

void HQMenuComponent::fillObjectMenuResponse(SceneObject* sceneObject, ObjectMenuResponse* menuResponse, CreatureObject* player) {
	ManagedReference<BuildingObject*> building = cast<BuildingObject*>(sceneObject->getParentRecursively(SceneObjectType::FACTIONBUILDING).get().get());

	if (building == NULL)
			return;

	Zone* zone = building->getZone();

	if(zone == NULL)
		return;

	GCWManager* gcwMan = zone->getGCWManager();

	ManagedReference<PlayerObject*> playerObject = player->getPlayerObject();
	if(playerObject == NULL)
		return;

	if(building->getFaction() == player->getFaction()) {

		menuResponse->addRadialMenuItem(228, 3, "@hq:mnu_defense_status");

		if(gcwMan->isShutdownSequenceStarted(building)){
			menuResponse->addRadialMenuItem(231, 3, "@hq:mnu_shutdown");  // Shutdown facility
		}

		// donate menus removed
		menuResponse->addRadialMenuItem(37, 3, "@hq:mnu_donate"); // Donate
		//menuResponse->addRadialMenuItemToRadialID(37, 225, 3,  "@hq:mnu_donate_money"); // Donate MOney
		menuResponse->addRadialMenuItemToRadialID(37, 226, 3, "@hq:mnu_donate_deed"); // donate defense
		//menuResponse->addRadialMenuItemToRadialID(37, 227, 3, "@hq:mnu_donate_resource"); // donate resource

		if(building->getOwnerCreatureObject() == player){
			menuResponse->addRadialMenuItem(38, 3, "@hq:mnu_reset_vulnerability"); // Reset Vulnerability
		}

	} else {

		if(playerObject->getFactionStatus() == FactionStatus::OVERT) {

			//menuResponse->addRadialMenuItem(228, 3, "@hq:mnu_defense_status");

			if(gcwMan->isPowerOverloaded(building) && !gcwMan->isShutdownSequenceStarted(building)){
				menuResponse->addRadialMenuItem(230, 3, "@hq:mnu_overload");  // activate overload
			}
		}
	}

	//if(true){

	// Admin menus to test out vulnerability manually
	/*
	if ( player->getPlayerObject()->isPrivileged()) {
		//info("player is privelaged", true);
		menuResponse->addRadialMenuItem(35, 3, "PVP EVENT");
		menuResponse->addRadialMenuItemToRadialID(35, MAKEIMPERIAL, 3, "MAKE VULNERABLE");
		menuResponse->addRadialMenuItemToRadialID(35, MAKENEUTRAL, 3, "MAKE INVULNERABLE");

	}
	*/

	//menuResponse->addRadialMenuItem(229, 3, "@player_structure:permission_destroy"); //Destroy Structure

}

int HQMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* creature, byte selectedID) {
	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();
	if (ghost == NULL)
		return 1;

	ManagedReference<BuildingObject*> building = cast<BuildingObject*>(sceneObject->getParentRecursively(SceneObjectType::FACTIONBUILDING).get().get());
	if(building == NULL)
		return 1;

	DestructibleBuildingDataComponent* baseData = getDestructibleBuildingDataComponent(building);

	if(baseData == NULL)
		return 1;

	Zone* zone = building->getZone();

	if(zone == NULL)
		return 1;

	ManagedReference<GCWManager*> gcwMan = zone->getGCWManager();

	if(gcwMan == NULL)
		return 1;

	if (selectedID == 20){
		if(creature->getFaction() == building->getFaction())
			gcwMan->sendStatus(building,creature);
	}
	else if( selectedID == 228 || selectedID == 20){

		if(ghost->getFactionStatus() != FactionStatus::OVERT && creature->getFaction() != building->getFaction()){
				creature->sendSystemMessage("@faction/faction_hq/faction_hq_response:declared_personnel_only"); // Only Special Forces personnel may access this terminal
				return 1;
		}

		gcwMan->sendBaseDefenseStatus(creature, building);
	} else if ( selectedID == 38) {
		gcwMan->sendResetVerification(creature, building);
	} else if ( selectedID == 229) {
		//info("Destroy base here",true);
		gcwMan->doBaseDestruction(building);
	} else if ( selectedID == 230 ) {
		creature->sendSystemMessage("BASE WILL BE DESTROYED UNLESS IT IS STOPPED");

		gcwMan->scheduleBaseDestruction(building);
	} else if (selectedID == 231) {
		//info("abort shutdown",true);
		gcwMan->abortShutdownSequence(creature,building);

	} else if (selectedID == 226){

		gcwMan->sendSelectDeedToDonate(building,creature,0);
	}
	return 0;
}

DestructibleBuildingDataComponent* HQMenuComponent::getDestructibleBuildingDataComponent(BuildingObject* building){
	DestructibleBuildingDataComponent* baseData = NULL;

	if (building != NULL){
		if(building->isGCWBase()){
			DataObjectComponentReference* data = building->getDataObjectComponent();

			if(data != NULL)
				baseData = cast<DestructibleBuildingDataComponent*>(data->get());

		}
	}

		return baseData;
}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical
 *  Center and contributors
 *
 *  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.txt
 *
 *  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 "selxNiftyregItkMultiStageComponent.h"
#include "selxCheckTemplateProperties.h"
#include "itkAffineTransform.h"

namespace selx
{
template< class InternalComputationValueType, int Dimensionality >
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::NiftyregItkMultiStageComponent( const std::string & name, LoggerImpl & logger ) : Superclass( name, logger )
{
  m_CompositeTransform = CompositeTransformType::New();

  //TODO: instantiating the filter in the constructor might be heavy for the use in component selector factory, since all components of the database are created during the selection process.
  // we could choose to keep the component light weighted (for checking criteria such as names and connections) until the settings are passed to the filter, but this requires an additional initialization step.
}

template< class InternalComputationValueType, int Dimensionality >
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::~NiftyregItkMultiStageComponent()
{
}

template< class InternalComputationValueType, int Dimensionality >
int
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::Accept( typename MultiStageTransformInterface< InternalComputationValueType, Dimensionality >::Pointer other )
{
  // todo how do we organize the fixedtransforms?
  this->m_RegistrationStages.insert( { other->GetComponentName(), other } );
  return 1;
}

template< class InternalComputationValueType, int Dimensionality >
int
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::Accept(typename NiftyregAffineMatrixInterface::Pointer other)
{
	this->m_NiftyregAffineMatrixInterface = other;
	return 1;
}

template< class InternalComputationValueType, int Dimensionality >
int
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::Accept( UpdateInterface::Pointer other )
{
	this->m_UpdateInterfaces.insert({ other->GetComponentName(), other });
  return 0;
}

template< class InternalComputationValueType, int Dimensionality >
typename NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::TransformType::Pointer
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::GetItkTransform()
{
  return ( typename TransformType::Pointer ) this->m_CompositeTransform;
}

template< class InternalComputationValueType, int Dimensionality >
void
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::Update()
{
  bool first = true;

  // Perform execution flow
  for( auto const & stageName : this->m_ExecutionOrder )
  {
    if (first)
    {
      m_UpdateInterfaces[stageName]->Update();
      // TODO check == null ?
      auto const & niftiMatrix = m_NiftyregAffineMatrixInterface->GetAffineNiftiMatrix()->m;

      using itkAffineTransformType = itk::AffineTransform<InternalComputationValueType, Dimensionality>;
      auto itkMatrix = itkAffineTransformType::MatrixType();
      auto itkTranslation = itkAffineTransformType::OffsetType();

      for ( unsigned int d1 = 0; d1 < Dimensionality; ++d1 )
      {
        for ( unsigned int d2 = 0; d2 < Dimensionality; ++d2 )
        {
          itkMatrix(d1,d2)=niftiMatrix[d1][d2];
        }
        itkTranslation[d1] = niftiMatrix[d1][3];
      }
      auto itkAffineTf = itkAffineTransformType::New();
      itkAffineTf->SetMatrix(itkMatrix);
      itkAffineTf->SetOffset(itkTranslation);
      this->m_CompositeTransform->AppendTransform( itkAffineTf );
      first=false;
    }
    else // continue with standard itk multistage
    {
	    m_RegistrationStages[stageName]->SetMovingInitialTransform( this->m_CompositeTransform );
      m_UpdateInterfaces[stageName]->Update();
      this->m_CompositeTransform->AppendTransform( m_RegistrationStages[stageName]->GetItkTransform() );
    }
  }
  return;
}

template< class InternalComputationValueType, int Dimensionality >
bool
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::MeetsCriterion( const ComponentBase::CriterionType & criterion )
{
  bool hasUndefinedCriteria( false );

  auto status = CheckTemplateProperties( this->TemplateProperties(), criterion );
  if( status == CriterionStatus::Satisfied )
  {
    return true;
  }
  else if( status == CriterionStatus::Failed )
  {
    return false;
  } // else: CriterionStatus::Unknown

  if( criterion.first == "ExecutionOrder" ) //Supports this?
  {
    // should we check on non-repeating names?
    this->m_ExecutionOrder = criterion.second;
    return true;
  }
  return hasUndefinedCriteria;
}

template< class InternalComputationValueType, int Dimensionality >
bool
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::ConnectionsSatisfied()
{
  // This function overrides the default behavior, in which all accepting interfaces must be set, by allowing the some interfaces not being set.
  // TODO: see I we can reduce the amount of code with helper (meta-)functions
  // A MultiStageTransformInterface connection is required
  if(! this->InterfaceAcceptor< MultiStageTransformInterface< InternalComputationValueType, Dimensionality >>::GetAccepted())
  {
    this->Error("Needs to have a MultiStageTransformInterface connected to it.",  this->m_Name);
    return false;
  }

  // A NiftyregAffineMatrixInterface connection is required
  if (!this->InterfaceAcceptor< NiftyregAffineMatrixInterface>::GetAccepted())
  {
    this->Error("Needs to have a NiftyregAffineMatrixInterface connected to it.",  this->m_Name);
    return false;
  }

  if ( 0 == this->m_ExecutionOrder.size())
  {
    this->Error("ExecutionOrder of {0} needs to be set with the names of the registration components. E.g. 'ExecutionOrder' : [ 'RegistrationMethod1', 'RegistrationMethod2' ] ", this->m_Name);
    return false;
  }
  // check if the component names in ExecutionOrder are connected both by MultiStageTransformInterface and UpdateInterface
  bool first = true;
  for( auto const & stageName : this->m_ExecutionOrder )
  {
    if (first)
    {
      if (m_NiftyregAffineMatrixInterface->GetComponentName()!=stageName)
      {
        this->Error("The first component '{0}' as named in the ExecutionOrder of '{1}' needs to be connected by  NiftyregAffineMatrixInterface. (Use named connections)", stageName, this->m_Name);
        return false;
      }
      first = false;
    }
	  else if (m_RegistrationStages.count(stageName)==0)
	  {
      this->Error("The component '{0}' as named in the ExecutionOrder of '{1}' needs to be connected by MultiStageTransformInterface. (Use named connections)", stageName, this->m_Name);
		  return false;
	  }
	  if (m_UpdateInterfaces.count(stageName) == 0)
	  {
      this->Error("The component '{0}' as named in the ExecutionOrder of '{1}' needs to be connected by UpdateInterface. (Use named connections)", stageName, this->m_Name);
		  return false;
	  }
  }

  if (m_RegistrationStages.size() > (m_ExecutionOrder.size()-1)) // assume 1 element in m_ExecutionOrder is from the NiftyregAffineMatrixInterface
  {
    this->Warning("'{0}' has unused MultiStageTransformInterface connections", this->m_Name);
  }
  if (m_UpdateInterfaces.size() > (m_ExecutionOrder.size()))
  {
    this->Warning("'{0}' has unused MultiStageTransformInterface connections", this->m_Name);
  }
  return true;
}
} //end namespace selx
<commit_msg>COMP: gcc requires typenames #212<commit_after>/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical
 *  Center and contributors
 *
 *  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.txt
 *
 *  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 "selxNiftyregItkMultiStageComponent.h"
#include "selxCheckTemplateProperties.h"
#include "itkAffineTransform.h"

namespace selx
{
template< class InternalComputationValueType, int Dimensionality >
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::NiftyregItkMultiStageComponent( const std::string & name, LoggerImpl & logger ) : Superclass( name, logger )
{
  m_CompositeTransform = CompositeTransformType::New();

  //TODO: instantiating the filter in the constructor might be heavy for the use in component selector factory, since all components of the database are created during the selection process.
  // we could choose to keep the component light weighted (for checking criteria such as names and connections) until the settings are passed to the filter, but this requires an additional initialization step.
}

template< class InternalComputationValueType, int Dimensionality >
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::~NiftyregItkMultiStageComponent()
{
}

template< class InternalComputationValueType, int Dimensionality >
int
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::Accept( typename MultiStageTransformInterface< InternalComputationValueType, Dimensionality >::Pointer other )
{
  // todo how do we organize the fixedtransforms?
  this->m_RegistrationStages.insert( { other->GetComponentName(), other } );
  return 1;
}

template< class InternalComputationValueType, int Dimensionality >
int
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::Accept(typename NiftyregAffineMatrixInterface::Pointer other)
{
	this->m_NiftyregAffineMatrixInterface = other;
	return 1;
}

template< class InternalComputationValueType, int Dimensionality >
int
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::Accept( UpdateInterface::Pointer other )
{
	this->m_UpdateInterfaces.insert({ other->GetComponentName(), other });
  return 0;
}

template< class InternalComputationValueType, int Dimensionality >
typename NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::TransformType::Pointer
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::GetItkTransform()
{
  return ( typename TransformType::Pointer ) this->m_CompositeTransform;
}

template< class InternalComputationValueType, int Dimensionality >
void
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >::Update()
{
  bool first = true;

  // Perform execution flow
  for( auto const & stageName : this->m_ExecutionOrder )
  {
    if (first)
    {
      m_UpdateInterfaces[stageName]->Update();
      // TODO check == null ?
      auto const & niftiMatrix = m_NiftyregAffineMatrixInterface->GetAffineNiftiMatrix()->m;

      using itkAffineTransformType = itk::AffineTransform<InternalComputationValueType, Dimensionality>;
      auto itkMatrix = typename itkAffineTransformType::MatrixType();
      auto itkTranslation = typename itkAffineTransformType::OffsetType();

      for ( unsigned int d1 = 0; d1 < Dimensionality; ++d1 )
      {
        for ( unsigned int d2 = 0; d2 < Dimensionality; ++d2 )
        {
          itkMatrix(d1,d2)=niftiMatrix[d1][d2];
        }
        itkTranslation[d1] = niftiMatrix[d1][3];
      }
      auto itkAffineTf = itkAffineTransformType::New();
      itkAffineTf->SetMatrix(itkMatrix);
      itkAffineTf->SetOffset(itkTranslation);
      this->m_CompositeTransform->AppendTransform( itkAffineTf );
      first=false;
    }
    else // continue with standard itk multistage
    {
	    m_RegistrationStages[stageName]->SetMovingInitialTransform( this->m_CompositeTransform );
      m_UpdateInterfaces[stageName]->Update();
      this->m_CompositeTransform->AppendTransform( m_RegistrationStages[stageName]->GetItkTransform() );
    }
  }
  return;
}

template< class InternalComputationValueType, int Dimensionality >
bool
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::MeetsCriterion( const ComponentBase::CriterionType & criterion )
{
  bool hasUndefinedCriteria( false );

  auto status = CheckTemplateProperties( this->TemplateProperties(), criterion );
  if( status == CriterionStatus::Satisfied )
  {
    return true;
  }
  else if( status == CriterionStatus::Failed )
  {
    return false;
  } // else: CriterionStatus::Unknown

  if( criterion.first == "ExecutionOrder" ) //Supports this?
  {
    // should we check on non-repeating names?
    this->m_ExecutionOrder = criterion.second;
    return true;
  }
  return hasUndefinedCriteria;
}

template< class InternalComputationValueType, int Dimensionality >
bool
NiftyregItkMultiStageComponent< InternalComputationValueType, Dimensionality >
::ConnectionsSatisfied()
{
  // This function overrides the default behavior, in which all accepting interfaces must be set, by allowing the some interfaces not being set.
  // TODO: see I we can reduce the amount of code with helper (meta-)functions
  // A MultiStageTransformInterface connection is required
  if(! this->InterfaceAcceptor< MultiStageTransformInterface< InternalComputationValueType, Dimensionality >>::GetAccepted())
  {
    this->Error("Needs to have a MultiStageTransformInterface connected to it.",  this->m_Name);
    return false;
  }

  // A NiftyregAffineMatrixInterface connection is required
  if (!this->InterfaceAcceptor< NiftyregAffineMatrixInterface>::GetAccepted())
  {
    this->Error("Needs to have a NiftyregAffineMatrixInterface connected to it.",  this->m_Name);
    return false;
  }

  if ( 0 == this->m_ExecutionOrder.size())
  {
    this->Error("ExecutionOrder of {0} needs to be set with the names of the registration components. E.g. 'ExecutionOrder' : [ 'RegistrationMethod1', 'RegistrationMethod2' ] ", this->m_Name);
    return false;
  }
  // check if the component names in ExecutionOrder are connected both by MultiStageTransformInterface and UpdateInterface
  bool first = true;
  for( auto const & stageName : this->m_ExecutionOrder )
  {
    if (first)
    {
      if (m_NiftyregAffineMatrixInterface->GetComponentName()!=stageName)
      {
        this->Error("The first component '{0}' as named in the ExecutionOrder of '{1}' needs to be connected by  NiftyregAffineMatrixInterface. (Use named connections)", stageName, this->m_Name);
        return false;
      }
      first = false;
    }
	  else if (m_RegistrationStages.count(stageName)==0)
	  {
      this->Error("The component '{0}' as named in the ExecutionOrder of '{1}' needs to be connected by MultiStageTransformInterface. (Use named connections)", stageName, this->m_Name);
		  return false;
	  }
	  if (m_UpdateInterfaces.count(stageName) == 0)
	  {
      this->Error("The component '{0}' as named in the ExecutionOrder of '{1}' needs to be connected by UpdateInterface. (Use named connections)", stageName, this->m_Name);
		  return false;
	  }
  }

  if (m_RegistrationStages.size() > (m_ExecutionOrder.size()-1)) // assume 1 element in m_ExecutionOrder is from the NiftyregAffineMatrixInterface
  {
    this->Warning("'{0}' has unused MultiStageTransformInterface connections", this->m_Name);
  }
  if (m_UpdateInterfaces.size() > (m_ExecutionOrder.size()))
  {
    this->Warning("'{0}' has unused MultiStageTransformInterface connections", this->m_Name);
  }
  return true;
}
} //end namespace selx
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include <iostream>

#include <boost/test/test_tools.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/output_test_stream.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>

#include "KDTreeTest.h"
#include "TypedDataTest.h"
#include "InterpolatorTest.h"
#include "IndexedIOTest.h"
#include "BoostUnitTestTest.h"
#include "MarchingCubesTest.h"
#include "DataConversionTest.h"
#include "DataConvertTest.h"
#include "DespatchTypedDataTest.h"
#include "CompilerTest.h"

using namespace boost::unit_test;
using boost::test_tools::output_test_stream;

using namespace IECore;

test_suite* init_unit_test_suite( int argc, char* argv[] )
{
	test_suite* test = BOOST_TEST_SUITE( "IECore unit test" );

	try
	{
		addBoostUnitTestTest(test);
		addKDTreeTest(test);
		addTypedDataTest(test);
		addInterpolatorTest(test);
		addIndexedIOTest(test);
		addMarchingCubesTest(test);
		addDataConversionTest(test);
		addDataConvertTest(test);
		addDespatchTypedDataTest(test);
		addCompilerTest(test);
	}
	catch (std::exception &ex)
	{
		std::cerr << "Failed to create test suite: " << ex.what() << std::endl;
		throw;
	}

	return test;
}
<commit_msg>Added call to RadixSort test<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include <iostream>

#include <boost/test/test_tools.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/output_test_stream.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>

#include "KDTreeTest.h"
#include "TypedDataTest.h"
#include "InterpolatorTest.h"
#include "IndexedIOTest.h"
#include "BoostUnitTestTest.h"
#include "MarchingCubesTest.h"
#include "DataConversionTest.h"
#include "DataConvertTest.h"
#include "DespatchTypedDataTest.h"
#include "CompilerTest.h"
#include "RadixSortTest.h"

using namespace boost::unit_test;
using boost::test_tools::output_test_stream;

using namespace IECore;

test_suite* init_unit_test_suite( int argc, char* argv[] )
{
	test_suite* test = BOOST_TEST_SUITE( "IECore unit test" );

	try
	{
		addBoostUnitTestTest(test);
		addKDTreeTest(test);
		addTypedDataTest(test);
		addInterpolatorTest(test);
		addIndexedIOTest(test);
		addMarchingCubesTest(test);
		addDataConversionTest(test);
		addDataConvertTest(test);
		addDespatchTypedDataTest(test);
		addCompilerTest(test);
		addRadixSortTest(test);
	}
	catch (std::exception &ex)
	{
		std::cerr << "Failed to create test suite: " << ex.what() << std::endl;
		throw;
	}

	return test;
}
<|endoftext|>


<commit_before>/**
 * \file
 * \brief SignalsCatcherControlBlock class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-04-23
 */

#ifndef INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
#define INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_

#include "distortos/SignalAction.hpp"

namespace distortos
{

namespace scheduler
{

class ThreadControlBlock;

}	// namespace scheduler

namespace synchronization
{

/// SignalsCatcherControlBlock class is a structure required by threads for "catching" and "handling" of signals
class SignalsCatcherControlBlock
{
public:

	/// association of signal number with SignalAction
	using Association = std::pair<uint8_t, SignalAction>;

	/// type of uninitialized storage for Association objects
	using Storage = std::aligned_storage<sizeof(Association), alignof(Association)>::type;

	/**
	 * \brief SignalsCatcherControlBlock's constructor
	 *
	 * \param [in] storageBegin is a pointer to first element of storage for Association objects
	 * \param [in] storageEnd is a pointer to "one past the last" element of storage for Association objects
	 */

	constexpr SignalsCatcherControlBlock(Storage* const storageBegin, Storage* const storageEnd) :
			signalMask_{SignalSet::empty},
			associationsBegin_{reinterpret_cast<decltype(associationsBegin_)>(storageBegin)},
			storageBegin_{storageBegin},
			storageEnd_{storageEnd}
	{

	}

	/**
	 * \brief Gets SignalAction associated with given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> getAssociation(uint8_t signalNumber) const;

	/**
	 * \return SignalSet with signal mask for associated thread
	 */

	SignalSet getSignalMask() const
	{
		return signalMask_;
	}

	/**
	 * \brief Part of SignalsReceiverControlBlock::postGenerate() specific to catching unmasked signals.
	 *
	 * Currently just a stub.
	 *
	 * \param [in] signalNumber is the unmasked signal that was generated, [0; 31]
	 * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	int postGenerate(uint8_t signalNumber, const scheduler::ThreadControlBlock& threadControlBlock) const;

	/**
	 * \brief Sets association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
	 * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object
	 * in internal storage is copy-constructed
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> setAssociation(uint8_t signalNumber, const SignalAction& signalAction);

	/**
	 * \param [in] signalMask is the SignalSet with new signal mask for associated thread
	 */

	void setSignalMask(const SignalSet signalMask)
	{
		signalMask_ = signalMask;
	}

private:

	/**
	 * \brief Clears association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
	 *
	 * \return SignalAction that was associated with \a signalNumber, default-constructed object if no association was
	 * found
	 */

	SignalAction clearAssociation(uint8_t signalNumber);

	/// SignalSet with signal mask for associated thread
	SignalSet signalMask_;

	/// pointer to first element of range of Association objects
	Association* associationsBegin_;

	/// union binds \a associationsEnd_ and \a storageBegin_ - these point to the same address
	union
	{
		/// pointer to "one past the last" element of range of Association objects
		Association* associationsEnd_;

		/// pointer to first element of range of Storage objects
		Storage* storageBegin_;
	};

	/// pointer to "one past the last" element of range of Storage objects
	Storage* storageEnd_;
};

}	// namespace synchronization

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
<commit_msg>SignalsCatcherControlBlock::postGenerate(): remove info about stub implementation and add proper comment<commit_after>/**
 * \file
 * \brief SignalsCatcherControlBlock class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-05-09
 */

#ifndef INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
#define INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_

#include "distortos/SignalAction.hpp"

namespace distortos
{

namespace scheduler
{

class ThreadControlBlock;

}	// namespace scheduler

namespace synchronization
{

/// SignalsCatcherControlBlock class is a structure required by threads for "catching" and "handling" of signals
class SignalsCatcherControlBlock
{
public:

	/// association of signal number with SignalAction
	using Association = std::pair<uint8_t, SignalAction>;

	/// type of uninitialized storage for Association objects
	using Storage = std::aligned_storage<sizeof(Association), alignof(Association)>::type;

	/**
	 * \brief SignalsCatcherControlBlock's constructor
	 *
	 * \param [in] storageBegin is a pointer to first element of storage for Association objects
	 * \param [in] storageEnd is a pointer to "one past the last" element of storage for Association objects
	 */

	constexpr SignalsCatcherControlBlock(Storage* const storageBegin, Storage* const storageEnd) :
			signalMask_{SignalSet::empty},
			associationsBegin_{reinterpret_cast<decltype(associationsBegin_)>(storageBegin)},
			storageBegin_{storageBegin},
			storageEnd_{storageEnd}
	{

	}

	/**
	 * \brief Gets SignalAction associated with given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association is requested, [0; 31]
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that is associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> getAssociation(uint8_t signalNumber) const;

	/**
	 * \return SignalSet with signal mask for associated thread
	 */

	SignalSet getSignalMask() const
	{
		return signalMask_;
	}

	/**
	 * \brief Part of SignalsReceiverControlBlock::postGenerate() specific to catching unmasked signals.
	 *
	 * Requests delivery of signals to associated thread if there is some non-default signal handler for the signal.
	 *
	 * \param [in] signalNumber is the unmasked signal that was generated, [0; 31]
	 * \param [in] threadControlBlock is a reference to associated ThreadControlBlock
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	int postGenerate(uint8_t signalNumber, const scheduler::ThreadControlBlock& threadControlBlock) const;

	/**
	 * \brief Sets association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be set, [0; 31]
	 * \param [in] signalAction is a reference to SignalAction that will be associated with given signal number, object
	 * in internal storage is copy-constructed
	 *
	 * \return pair with return code (0 on success, error code otherwise) and SignalAction that was associated with
	 * \a signalNumber, default-constructed object if no association was found;
	 * error codes:
	 * - EAGAIN - no resources are available to associate \a signalNumber with \a signalAction;
	 * - EINVAL - \a signalNumber value is invalid;
	 */

	std::pair<int, SignalAction> setAssociation(uint8_t signalNumber, const SignalAction& signalAction);

	/**
	 * \param [in] signalMask is the SignalSet with new signal mask for associated thread
	 */

	void setSignalMask(const SignalSet signalMask)
	{
		signalMask_ = signalMask;
	}

private:

	/**
	 * \brief Clears association for given signal number.
	 *
	 * \param [in] signalNumber is the signal for which the association will be cleared, [0; 31]
	 *
	 * \return SignalAction that was associated with \a signalNumber, default-constructed object if no association was
	 * found
	 */

	SignalAction clearAssociation(uint8_t signalNumber);

	/// SignalSet with signal mask for associated thread
	SignalSet signalMask_;

	/// pointer to first element of range of Association objects
	Association* associationsBegin_;

	/// union binds \a associationsEnd_ and \a storageBegin_ - these point to the same address
	union
	{
		/// pointer to "one past the last" element of range of Association objects
		Association* associationsEnd_;

		/// pointer to first element of range of Storage objects
		Storage* storageBegin_;
	};

	/// pointer to "one past the last" element of range of Storage objects
	Storage* storageEnd_;
};

}	// namespace synchronization

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_SYNCHRONIZATION_SIGNALSCATCHERCONTROLBLOCK_HPP_
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2014 Max-Planck-Institute for Intelligent Systems,
 *                     University of Southern California
 *    Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *    Jan Issac (jan.issac@gmail.com)
 *
 *
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 * @date 05/25/2014
 * @author Manuel Wuthrich (manuel.wuthrich@gmail.com)
 * @author Jan Issac (jan.issac@gmail.com)
 * Max-Planck-Institute for Intelligent Systems, University of Southern California
 */

#ifndef FAST_FILTERING_DISTRIBUTIONS_INTERFACES_GAUSSIAN_MAP_HPP
#define FAST_FILTERING_DISTRIBUTIONS_INTERFACES_GAUSSIAN_MAP_HPP

#include <Eigen/Dense>

#include <boost/random/normal_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>

#include <fast_filtering/utils/assertions.hpp>
#include <fast_filtering/utils/traits.hpp>
#include <fast_filtering/distributions/interfaces/sampling.hpp>
#include <fast_filtering/distributions/standard_gaussian.hpp>

namespace ff
{

template <typename Vector, typename Noise = internal::Empty>
class GaussianMap:
        public Sampling<Vector>
{
public:
    explicit GaussianMap(const unsigned& noise_dimension = Noise::SizeAtCompileTime):
        standard_gaussian_(noise_dimension)
    {
        // make sure that noise is derived from eigen
        REQUIRE_INTERFACE(Noise, Eigen::Matrix<typename Noise::Scalar, Noise::SizeAtCompileTime, 1>);
    }

    virtual ~GaussianMap() { }

    virtual Vector MapStandardGaussian(const Noise& sample) const = 0;

    virtual Vector Sample()
    {
        return MapStandardGaussian(standard_gaussian_.Sample());
    }

    virtual int NoiseDimension() const
    {
        return standard_gaussian_.Dimension();
    }

private:
    StandardGaussian<Noise> standard_gaussian_;
};

// specialization for scalar noise
template <typename Vector>
class GaussianMap<Vector, double>:
        public Sampling<Vector>
{
public:
    virtual ~GaussianMap() { }

    virtual Vector MapStandardGaussian(const double& sample) const = 0;

    virtual Vector Sample()
    {
        return MapStandardGaussian(standard_gaussian_.Sample());
    }

    virtual int NoiseDimension() const
    {
        return 1;
    }
private:
    StandardGaussian<double> standard_gaussian_;
};

// specialization for no noise
template <typename Vector>
class GaussianMap<Vector, internal::Empty>:
        public Sampling<Vector>
{
public:
    virtual ~GaussianMap() { }

    virtual Vector MapStandardGaussian() const = 0;

    virtual Vector Sample()
    {
        return MapStandardGaussian();
    }

    virtual int NoiseDimension() const
    {
        return 0;
    }
};

}

#endif
<commit_msg>Added static_assert_dynamic_sized and static_assert_const_sized usage. It's been however deactivated for the time being until the entire library is adapted to this.<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2014 Max-Planck-Institute for Intelligent Systems,
 *                     University of Southern California
 *    Manuel Wuthrich (manuel.wuthrich@gmail.com)
 *    Jan Issac (jan.issac@gmail.com)
 *
 *
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 * @date 05/25/2014
 * @author Manuel Wuthrich (manuel.wuthrich@gmail.com)
 * @author Jan Issac (jan.issac@gmail.com)
 * Max-Planck-Institute for Intelligent Systems, University of Southern California
 */

#ifndef FAST_FILTERING_DISTRIBUTIONS_INTERFACES_GAUSSIAN_MAP_HPP
#define FAST_FILTERING_DISTRIBUTIONS_INTERFACES_GAUSSIAN_MAP_HPP

#include <Eigen/Dense>

#include <boost/random/normal_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/variate_generator.hpp>

#include <fast_filtering/utils/assertions.hpp>
#include <fast_filtering/utils/traits.hpp>
#include <fast_filtering/distributions/interfaces/sampling.hpp>
#include <fast_filtering/distributions/standard_gaussian.hpp>

namespace ff
{

template <typename Vector, typename Noise = internal::Empty>
class GaussianMap:
        public Sampling<Vector>
{
public:
    explicit GaussianMap(const unsigned& noise_dimension = Noise::SizeAtCompileTime):
        standard_gaussian_(noise_dimension)
    {
        //static_assert_dynamic_sized(Noise);
        static_assert_base(Noise,
                           Eigen::Matrix<typename Noise::Scalar,
                                         Noise::SizeAtCompileTime, 1>);
    }

//    GaussianMap()
//    {
//        //static_assert_const_sized(Noise);
//        static_assert_base(Noise,
//                           Eigen::Matrix<typename Noise::Scalar,
//                                         Noise::SizeAtCompileTime, 1>);
//    }

    virtual ~GaussianMap() { }

    virtual Vector MapStandardGaussian(const Noise& sample) const = 0;

    virtual Vector Sample()
    {
        return MapStandardGaussian(standard_gaussian_.Sample());
    }

    virtual int NoiseDimension() const
    {
        return standard_gaussian_.Dimension();
    }

private:
    StandardGaussian<Noise> standard_gaussian_;
};

// specialization for scalar noise
template <typename Vector>
class GaussianMap<Vector, double>:
        public Sampling<Vector>
{
public:
    virtual ~GaussianMap() { }

    virtual Vector MapStandardGaussian(const double& sample) const = 0;

    virtual Vector Sample()
    {
        return MapStandardGaussian(standard_gaussian_.Sample());
    }

    virtual int NoiseDimension() const
    {
        return 1;
    }
private:
    StandardGaussian<double> standard_gaussian_;
};

// specialization for no noise
template <typename Vector>
class GaussianMap<Vector, internal::Empty>:
        public Sampling<Vector>
{
public:
    virtual ~GaussianMap() { }

    virtual Vector MapStandardGaussian() const = 0;

    virtual Vector Sample()
    {
        return MapStandardGaussian();
    }

    virtual int NoiseDimension() const
    {
        return 0;
    }
};

}

#endif
<|endoftext|>


<commit_before>#define DO_UNIT_TESTING 1

#if DO_UNIT_TESTING==1

#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file

#include <catch.hpp>

//Unit test files
#include "MathTests.h"

#endif
<commit_msg>comments<commit_after>#define DO_UNIT_TESTING 1

#if DO_UNIT_TESTING==1

//Catch provides a main that takes precedence
#define CATCH_CONFIG_MAIN

#include <catch.hpp>

//Unit test files
#include "MathTests.h"

#endif
<|endoftext|>


<commit_before>/*
 * Quantum++
 *
 * Copyright (c) 2013 - 2014 Vlad Gheorghiu (vgheorgh@gmail.com)
 *
 * This file is part of Quantum++.
 *
 * Quantum++ is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Quantum++ 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 General Public License
 * along with Quantum++.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qpp.h"

// #include "MATLAB/matlab.h" // support for MATLAB

using namespace qpp;

int main()
{
    // Qudit Teleportation
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Teleportation, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_aA = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        ket psi_a = randket(D); // random state as input on a
        std::cout << ">> Initial state:" << std::endl;
        std::cout << disp(psi_a) << std::endl;
        ket input_aAB = kron(psi_a, mes_AB); // joint input state aAB
        // output before measurement
        ket output_aAB = apply(input_aAB, Bell_aA, {0, 1}, 3, D);
        auto measured_aA = measure(ptrace2(prj(output_aAB), {D * D, D}), gt.Id(D * D)); // measure on aA
        std::discrete_distribution<std::size_t> dd(measured_aA.first.begin(), measured_aA.first.end());
        std::cout << ">> Alice's measurement probabilities: ";
        std::cout << disp(measured_aA.first, ", ") << std::endl;
        std::size_t m = dd(rdevs._rng); // sample
        auto midx = n2multiidx(m, {D, D});
        std::cout << ">> Alice's measurement result: ";
        std::cout << disp(midx, " ") << std::endl;
        // conditional result on B before correction
        ket output_m_aAB = apply(output_aAB, prj(mket(midx, D)), {0, 1}, 3, D) / std::sqrt(measured_aA.first[m]);
        cmat correction_B = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]); // correction operator
        // apply correction on B
        output_aAB = apply(output_m_aAB, correction_B, {2}, 3, D);
        cmat rho_B = ptrace1(prj(output_aAB), {D * D, D});
        std::cout << ">> Bob's density operator: " << std::endl;
        std::cout << disp(rho_B) << std::endl;
        std::cout << ">> Norm difference: " << norm(rho_B - prj(psi_a)) << std::endl; // verification
    }

    // Qudit Dense Coding
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Dense Coding, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_AB = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        // equal probabilities of choosing a message
        std::uniform_int_distribution<std::size_t> uid(0, D * D - 1);
        std::size_t m_A = uid(rdevs._rng); // sample, obtain the message index
        auto midx = n2multiidx(m_A, {D, D});
        std::cout << ">> Alice sent: ";
        std::cout << disp(midx, " ") << std::endl;
        // Alice's operation
        cmat U_A = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]);
        // Alice encodes the message
        ket psi_AB = apply(mes_AB, U_A, {0}, 2, D);
        // Bob measures the joint system in the qudit Bell basis
        psi_AB = apply(psi_AB, Bell_AB, {0, 1}, 2, D);
        auto measured = measure(psi_AB, gt.Id(D * D));
        std::cout << ">> Bob's measurement probabilities: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        // Bob samples according to the measurement probabilities
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t m_B = dd(rdevs._rng);
        std::cout << ">> Bob received: ";
        std::cout << disp(n2multiidx(m_B, {D, D}), " ") << std::endl;
    }

    // Grover's search algorithm, we time it
    {
        Timer t; // set a timer
        std::size_t n = 4; // number of qubits
        std::cout << std::endl << "**** Grover on n = " << n << " qubits ****" << std::endl;
        std::vector<std::size_t> dims(n, 2); // local dimensions
        std::size_t N = std::pow(2, n); // number of elements in the database
        std::cout << ">> Database size: " << N << std::endl;
        // mark an element randomly
        std::uniform_int_distribution<std::size_t> uid(0, N - 1);
        std::size_t marked = uid(rdevs._rng);
        std::cout << ">> Marked state: " << marked << " -> ";
        std::cout << disp(n2multiidx(marked, dims), " ") << std::endl;
        ket psi = mket(n2multiidx(0, dims)); // computational |0>^\otimes n
        psi = (kronpow(gt.H, n) * psi).eval(); // apply H^\otimes n, no aliasing
        cmat G = 2 * prj(psi) - gt.Id(N); // Diffusion operator
        // number of queries
        std::size_t nqueries = std::ceil(pi * std::sqrt(N) / 4.);
        std::cout << ">> We run " << nqueries << " queries" << std::endl;
        for (std::size_t i = 0; i < nqueries; i++)
        {
            psi(marked) = -psi(marked); // apply the oracle first, no aliasing
            psi = (G * psi).eval(); // then the diffusion operator, no aliasing
        }
        // we now measure the state in the computational basis
        auto measured = measure(psi, gt.Id(N));
        std::cout << ">> Probability of the marked state: " << measured.first[marked] << std::endl;
        std::cout << ">> Probability of all results: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        std::cout << ">> Let's sample..." << std::endl;
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t result = dd(rdevs._rng);
        if (result == marked)
            std::cout << ">> Hooray, we obtained the correct result: ";
        else
            std::cout << ">> Not there yet... we obtained: ";
        std::cout << result << " -> ";
        std::cout << disp(n2multiidx(result, dims), " ") << std::endl;
        // stop the timer and display it
        std::cout << ">> It took " << t.toc() << " seconds to simulate Grover on " << n << " qubits." << std::endl;
    }

    // Entanglement
    {
        std::cout << std::endl << "**** Entanglement ****" << std::endl;
        cmat rho = 0.2 * st.pb00 + 0.8 * st.pb11;
        std::cout << ">> rho: " << std::endl;
        std::cout << disp(rho) << std::endl;
        std::cout << ">> Concurrence of rho: " << concurrence(rho) << std::endl;
        std::cout << ">> Negativity of rho: " << negativity(rho, {2, 2}) << std::endl;
        std::cout << ">> Logarithimc negativity of rho: " << lognegativity(rho, {2, 2}) << std::endl;
        ket psi = 0.8 * mket({0, 0}) + 0.6 * mket({1, 1});
        // apply some local random unitaries
        psi = kron(randU(2), randU(2)) * psi;
        std::cout << ">> psi: " << std::endl;
        std::cout << disp(psi) << std::endl;
        std::cout << ">> Entanglement of psi: " << entanglement(psi, {2, 2}) << std::endl;
        std::cout << ">> Concurrence of psi: " << concurrence(prj(psi)) << std::endl;
        std::cout << ">> G-Concurrence of psi: " << gconcurrence(psi) << std::endl;
        std::cout << ">> Schmidt coefficients of psi: " << std::endl;
        std::cout << disp(schmidtcoeff(psi, {2, 2})) << std::endl;
        std::cout << ">> Schmidt probabilities of psi: " << std::endl;
        std::cout << disp(schmidtprob(psi, {2, 2})) << std::endl;
        cmat U = schmidtU(psi, {2, 2});
        cmat V = schmidtV(psi, {2, 2});
        std::cout << ">> Schmidt vectors on Alice's side: " << std::endl;
        std::cout << disp(U) << std::endl;
        std::cout << ">> Schmidt vectors on Bob's side: " << std::endl;
        std::cout << disp(V) << std::endl;
        std::cout << ">> State psi in the Schmidt basis: " << std::endl;
        std::cout << disp(adjoint(kron(U, V)) * psi) << std::endl;
        // reconstructed state
        ket psi_from_schmidt = schmidtcoeff(psi, {2, 2})(0) * kron(U.col(0), V.col(0)) +
                schmidtcoeff(psi, {2, 2})(1) * kron(U.col(1), V.col(1));
        std::cout << ">> State psi reconstructed from the Schmidt decomposition: " << std::endl;
        std::cout << disp(psi_from_schmidt) << std::endl;
        std::cout << ">> Norm difference: " << norm(psi - psi_from_schmidt) << std::endl;
    }

    // Quantum error correcting codes
    {
        std::cout << std::endl << "**** Quantum error correcting codes ****" << std::endl;
        ket a0 = codes.codeword(Codes::Type::FIVE_QUBIT, 0);
        ket a1 = codes.codeword(Codes::Type::FIVE_QUBIT, 1);
        ket b0 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 0);
        ket b1 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 1);
        ket c0 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 0);
        ket c1 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 1);
        std::cout << ">> [[5, 1, 3]] Five qubit code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L|1L> = ";
        std::cout << disp(adjoint(a0) * a1) << std::endl;
        std::cout << ">> [[7, 1, 3]] Seven qubit Steane code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L|1L> = ";
        std::cout << disp(adjoint(b0) * b1) << std::endl;
        std::cout << ">> [[9, 1, 3]] Nine qubit Shor code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> <0L|1L> = ";
        std::cout << disp(adjoint(c0) * c1) << std::endl;
    }
}
<commit_msg>commit<commit_after>/*
 * Quantum++
 *
 * Copyright (c) 2013 - 2014 Vlad Gheorghiu (vgheorgh@gmail.com)
 *
 * This file is part of Quantum++.
 *
 * Quantum++ is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Quantum++ 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 General Public License
 * along with Quantum++.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qpp.h"

// #include "MATLAB/matlab.h" // support for MATLAB

using namespace qpp;

int main()
{
    // Qudit Teleportation
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Teleportation, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_aA = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        ket psi_a = randket(D); // random state as input on a
        std::cout << ">> Initial state:" << std::endl;
        std::cout << disp(psi_a) << std::endl;
        ket input_aAB = kron(psi_a, mes_AB); // joint input state aAB
        // output before measurement
        ket output_aAB = apply(input_aAB, Bell_aA, {0, 1}, 3, D);
        auto measured_aA = measure(ptrace2(prj(output_aAB), {D * D, D}), gt.Id(D * D)); // measure on aA
        std::discrete_distribution<std::size_t> dd(measured_aA.first.begin(), measured_aA.first.end());
        std::cout << ">> Alice's measurement probabilities: ";
        std::cout << disp(measured_aA.first, ", ") << std::endl;
        std::size_t m = dd(rdevs._rng); // sample
        auto midx = n2multiidx(m, {D, D});
        std::cout << ">> Alice's measurement result: ";
        std::cout << disp(midx, " ") << std::endl;
        // conditional result on B before correction
        ket output_m_aAB = apply(output_aAB, prj(mket(midx, D)), {0, 1}, 3, D) / std::sqrt(measured_aA.first[m]);
        cmat correction_B = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]); // correction operator
        // apply correction on B
        output_aAB = apply(output_m_aAB, correction_B, {2}, 3, D);
        cmat rho_B = ptrace1(prj(output_aAB), {D * D, D});
        std::cout << ">> Bob's density operator: " << std::endl;
        std::cout << disp(rho_B) << std::endl;
        std::cout << ">> Norm difference: " << norm(rho_B - prj(psi_a)) << std::endl; // verification
    }

    // Qudit Dense Coding
    {
        std::size_t D = 3; // size of the system
        std::cout << std::endl << "**** Qudit Dense Coding, D = " << D << " ****" << std::endl;
        ket mes_AB = ket::Zero(D * D); // maximally entangled state resource
        for (std::size_t i = 0; i < D; i++)
            mes_AB += mket({i, i}, D);
        mes_AB /= std::sqrt((double) D);
        // circuit that measures in the qudit Bell basis
        cmat Bell_AB = adjoint(gt.CTRL(gt.Xd(D), {0}, {1}, 2, D) * kron(gt.Fd(D), gt.Id(D)));
        // equal probabilities of choosing a message
        std::uniform_int_distribution<std::size_t> uid(0, D * D - 1);
        std::size_t m_A = uid(rdevs._rng); // sample, obtain the message index
        auto midx = n2multiidx(m_A, {D, D});
        std::cout << ">> Alice sent: ";
        std::cout << disp(midx, " ") << std::endl;
        // Alice's operation
        cmat U_A = powm(gt.Zd(D), midx[0]) * powm(adjoint(gt.Xd(D)), midx[1]);
        // Alice encodes the message
        ket psi_AB = apply(mes_AB, U_A, {0}, 2, D);
        // Bob measures the joint system in the qudit Bell basis
        psi_AB = apply(psi_AB, Bell_AB, {0, 1}, 2, D);
        auto measured = measure(psi_AB, gt.Id(D * D));
        std::cout << ">> Bob's measurement probabilities: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        // Bob samples according to the measurement probabilities
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t m_B = dd(rdevs._rng);
        std::cout << ">> Bob received: ";
        std::cout << disp(n2multiidx(m_B, {D, D}), " ") << std::endl;
    }

    // Grover's search algorithm, we time it
    {
        Timer t; // set a timer
        std::size_t n = 4; // number of qubits
        std::cout << std::endl << "**** Grover on n = " << n << " qubits ****" << std::endl;
        std::vector<std::size_t> dims(n, 2); // local dimensions
        std::size_t N = std::pow(2, n); // number of elements in the database
        std::cout << ">> Database size: " << N << std::endl;
        // mark an element randomly
        std::uniform_int_distribution<std::size_t> uid(0, N - 1);
        std::size_t marked = uid(rdevs._rng);
        std::cout << ">> Marked state: " << marked << " -> ";
        std::cout << disp(n2multiidx(marked, dims), " ") << std::endl;
        ket psi = mket(n2multiidx(0, dims)); // computational |0>^\otimes n
        psi = (kronpow(gt.H, n) * psi).eval(); // apply H^\otimes n, no aliasing
        cmat G = 2 * prj(psi) - gt.Id(N); // Diffusion operator
        // number of queries
        std::size_t nqueries = std::ceil(pi * std::sqrt(N) / 4.);
        std::cout << ">> We run " << nqueries << " queries" << std::endl;
        for (std::size_t i = 0; i < nqueries; i++)
        {
            psi(marked) = -psi(marked); // apply the oracle first, no aliasing
            psi = (G * psi).eval(); // then the diffusion operator, no aliasing
        }
        // we now measure the state in the computational basis
        auto measured = measure(psi, gt.Id(N));
        std::cout << ">> Probability of the marked state: " << measured.first[marked] << std::endl;
        std::cout << ">> Probability of all results: ";
        std::cout << disp(measured.first, ", ") << std::endl;
        std::cout << ">> Let's sample..." << std::endl;
        std::discrete_distribution<std::size_t> dd(measured.first.begin(), measured.first.end());
        std::size_t result = dd(rdevs._rng);
        if (result == marked)
            std::cout << ">> Hooray, we obtained the correct result: ";
        else
            std::cout << ">> Not there yet... we obtained: ";
        std::cout << result << " -> ";
        std::cout << disp(n2multiidx(result, dims), " ") << std::endl;
        // stop the timer and display it
        std::cout << ">> It took " << t.toc() << " seconds to simulate Grover on " << n << " qubits." << std::endl;
    }

    // Entanglement
    {
        std::cout << std::endl << "**** Entanglement ****" << std::endl;
        cmat rho = 0.2 * st.pb00 + 0.8 * st.pb11;
        std::cout << ">> rho: " << std::endl;
        std::cout << disp(rho) << std::endl;
        std::cout << ">> Concurrence of rho: " << concurrence(rho) << std::endl;
        std::cout << ">> Negativity of rho: " << negativity(rho, {2, 2}) << std::endl;
        std::cout << ">> Logarithimc negativity of rho: " << lognegativity(rho, {2, 2}) << std::endl;
        ket psi = 0.8 * mket({0, 0}) + 0.6 * mket({1, 1});
        // apply some local random unitaries
        psi = kron(randU(2), randU(2)) * psi;
        std::cout << ">> psi: " << std::endl;
        std::cout << disp(psi) << std::endl;
        std::cout << ">> Entanglement of psi: " << entanglement(psi, {2, 2}) << std::endl;
        std::cout << ">> Concurrence of psi: " << concurrence(prj(psi)) << std::endl;
        std::cout << ">> G-Concurrence of psi: " << gconcurrence(psi) << std::endl;
        std::cout << ">> Schmidt coefficients of psi: " << std::endl;
        std::cout << disp(schmidtcoeff(psi, {2, 2})) << std::endl;
        std::cout << ">> Schmidt probabilities of psi: " << std::endl;
        std::cout << disp(schmidtprob(psi, {2, 2})) << std::endl;
        cmat U = schmidtU(psi, {2, 2});
        cmat V = schmidtV(psi, {2, 2});
        std::cout << ">> Schmidt vectors on Alice's side: " << std::endl;
        std::cout << disp(U) << std::endl;
        std::cout << ">> Schmidt vectors on Bob's side: " << std::endl;
        std::cout << disp(V) << std::endl;
        std::cout << ">> State psi in the Schmidt basis: " << std::endl;
        std::cout << disp(adjoint(kron(U, V)) * psi) << std::endl;
        // reconstructed state
        ket psi_from_schmidt = schmidtcoeff(psi, {2, 2})(0) * kron(U.col(0), V.col(0)) +
                schmidtcoeff(psi, {2, 2})(1) * kron(U.col(1), V.col(1));
        std::cout << ">> State psi reconstructed from the Schmidt decomposition: " << std::endl;
        std::cout << disp(psi_from_schmidt) << std::endl;
        std::cout << ">> Norm difference: " << norm(psi - psi_from_schmidt) << std::endl;
    }

    // Quantum error correcting codes
    {
        std::cout << std::endl << "**** Quantum error correcting codes ****" << std::endl;
        ket a0 = codes.codeword(Codes::Type::FIVE_QUBIT, 0);
        ket a1 = codes.codeword(Codes::Type::FIVE_QUBIT, 1);
        ket b0 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 0);
        ket b1 = codes.codeword(Codes::Type::SEVEN_QUBIT_STEANE, 1);
        ket c0 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 0);
        ket c1 = codes.codeword(Codes::Type::NINE_QUBIT_SHOR, 1);
        std::cout << ">> [[5, 1, 3]] Five qubit code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> |<0L|1L>| = ";
        std::cout << disp(adjoint(a0) * a1) << std::endl;
        std::cout << ">> [[7, 1, 3]] Seven qubit Steane code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> |<0L|1L>| = ";
        std::cout << disp(adjoint(b0) * b1) << std::endl;
        std::cout << ">> [[9, 1, 3]] Nine qubit Shor code. ";
        std::cout << "Checking codeword orthogonality." << std::endl;
        std::cout << ">> |<0L|1L>| = ";
        std::cout << disp(adjoint(c0) * c1) << std::endl;
    }
}
<|endoftext|>


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

#include "cells.h"
#include "design_utils.h"
#include "log.h"
#include "nextpnr.h"
#include "timing.h"
#include "util.h"
NEXTPNR_NAMESPACE_BEGIN

inline NetInfo *port_or_nullptr(const CellInfo *cell, IdString name)
{
    auto found = cell->ports.find(name);
    if (found == cell->ports.end())
        return nullptr;
    return found->second.net;
}

bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
{
    // TODO: allow different LSR/CLK and MUX/SRMODE settings once
    // routing details are worked out
    IdString clk_sig, lsr_sig;
    IdString CLKMUX, LSRMUX, SRMODE;
    bool first = true;
    for (auto cell : cells) {
        if (cell->sliceInfo.using_dff) {
            if (first) {
                clk_sig = cell->sliceInfo.clk_sig;
                lsr_sig = cell->sliceInfo.lsr_sig;
                CLKMUX = cell->sliceInfo.clkmux;
                LSRMUX = cell->sliceInfo.lsrmux;
                SRMODE = cell->sliceInfo.srmode;
            } else {
                if (cell->sliceInfo.clk_sig != clk_sig)
                    return false;
                if (cell->sliceInfo.lsr_sig != lsr_sig)
                    return false;
                if (cell->sliceInfo.clkmux != CLKMUX)
                    return false;
                if (cell->sliceInfo.lsrmux != LSRMUX)
                    return false;
                if (cell->sliceInfo.srmode != SRMODE)
                    return false;
            }
            first = false;
        }
    }
    return true;
}

bool Arch::isBelLocationValid(BelId bel) const
{
    if (getBelType(bel) == id_TRELLIS_SLICE) {
        std::vector<const CellInfo *> bel_cells;
        Loc bel_loc = getBelLocation(bel);
        for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
            CellInfo *cell_other = getBoundBelCell(bel_other);
            if (cell_other != nullptr) {
                bel_cells.push_back(cell_other);
            }
        }
        if (getBoundBelCell(bel) != nullptr && getBoundBelCell(bel)->sliceInfo.has_l6mux && ((bel_loc.z % 2) == 1))
            return false;
        return slicesCompatible(bel_cells);
    } else {
        CellInfo *cell = getBoundBelCell(bel);
        if (cell == nullptr)
            return true;
        else
            return isValidBelForCell(cell, bel);
    }
}

bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{
    if (cell->type == id_TRELLIS_SLICE) {
        NPNR_ASSERT(getBelType(bel) == id_TRELLIS_SLICE);

        std::vector<const CellInfo *> bel_cells;
        Loc bel_loc = getBelLocation(bel);

        if (cell->sliceInfo.has_l6mux && ((bel_loc.z % 2) == 1))
            return false;

        for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
            CellInfo *cell_other = getBoundBelCell(bel_other);
            if (cell_other != nullptr && bel_other != bel) {
                bel_cells.push_back(cell_other);
            }
        }

        bel_cells.push_back(cell);
        return slicesCompatible(bel_cells);
    } else if (cell->type == id_DCUA || cell->type == id_EXTREFB || cell->type == id_PCSCLKDIV) {
        return args.type != ArchArgs::LFE5U_25F && args.type != ArchArgs::LFE5U_45F && args.type != ArchArgs::LFE5U_85F;
    } else {
        // other checks
        return true;
    }
}

void Arch::permute_luts()
{
    NetCriticalityMap nc;
    get_criticalities(getCtx(), &nc);

    std::unordered_map<PortInfo *, size_t> port_to_user;
    for (auto net : sorted(nets)) {
        NetInfo *ni = net.second;
        for (size_t i = 0; i < ni->users.size(); i++) {
            auto &usr = ni->users.at(i);
            port_to_user[&(usr.cell->ports.at(usr.port))] = i;
        }
    }

    auto proc_lut = [&](CellInfo *ci, int lut) {
        std::vector<IdString> port_names;
        for (int i = 0; i < 4; i++)
            port_names.push_back(id(std::string("ABCD").substr(i, 1) + std::to_string(lut)));

        std::vector<std::pair<float, int>> inputs;
        std::vector<NetInfo *> orig_nets;

        for (int i = 0; i < 4; i++) {
            auto &port = ci->ports.at(port_names.at(i));
            float crit = 0;
            if (port.net != nullptr && nc.count(port.net->name)) {
                auto &n = nc.at(port.net->name);
                size_t usr = port_to_user.at(&port);
                if (usr < n.criticality.size())
                    crit = n.criticality.at(usr);
            }
            orig_nets.push_back(port.net);
            inputs.emplace_back(crit, i);
        }
        // Least critical first (A input is slowest)

        // Avoid permuting locked LUTs (e.g. from an OOC submodule)
        if (ci->belStrength <= STRENGTH_STRONG)
            std::sort(inputs.begin(), inputs.end());
        for (int i = 0; i < 4; i++) {
            IdString p = port_names.at(i);
            // log_info("%s %s %f\n", p.c_str(ctx), port_names.at(inputs.at(i).second).c_str(ctx), inputs.at(i).first);
            disconnect_port(getCtx(), ci, p);
            ci->ports.at(p).net = nullptr;
            if (orig_nets.at(inputs.at(i).second) != nullptr) {
                connect_port(getCtx(), orig_nets.at(inputs.at(i).second), ci, p);
                ci->params[id(p.str(this) + "MUX")] = p.str(this);
            } else {
                ci->params[id(p.str(this) + "MUX")] = std::string("1");
            }
        }
        // Rewrite function
        int old_init = int_or_default(ci->params, id("LUT" + std::to_string(lut) + "_INITVAL"), 0);
        int new_init = 0;
        for (int i = 0; i < 16; i++) {
            int old_index = 0;
            for (int k = 0; k < 4; k++) {
                if (i & (1 << k))
                    old_index |= (1 << inputs.at(k).second);
            }
            if (old_init & (1 << old_index))
                new_init |= (1 << i);
        }
        ci->params[id("LUT" + std::to_string(lut) + "_INITVAL")] = Property(new_init, 16);
    };

    for (auto cell : sorted(cells)) {
        CellInfo *ci = cell.second;
        if (ci->type == id_TRELLIS_SLICE && str_or_default(ci->params, id("MODE"), "LOGIC") == "LOGIC") {
            proc_lut(ci, 0);
            proc_lut(ci, 1);
        }
    }
}

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

#include "cells.h"
#include "design_utils.h"
#include "log.h"
#include "nextpnr.h"
#include "timing.h"
#include "util.h"
NEXTPNR_NAMESPACE_BEGIN

inline NetInfo *port_or_nullptr(const CellInfo *cell, IdString name)
{
    auto found = cell->ports.find(name);
    if (found == cell->ports.end())
        return nullptr;
    return found->second.net;
}

bool Arch::slicesCompatible(const std::vector<const CellInfo *> &cells) const
{
    // TODO: allow different LSR/CLK and MUX/SRMODE settings once
    // routing details are worked out
    IdString clk_sig, lsr_sig;
    IdString CLKMUX, LSRMUX, SRMODE;
    bool first = true;
    for (auto cell : cells) {
        if (cell->sliceInfo.using_dff) {
            if (first) {
                clk_sig = cell->sliceInfo.clk_sig;
                lsr_sig = cell->sliceInfo.lsr_sig;
                CLKMUX = cell->sliceInfo.clkmux;
                LSRMUX = cell->sliceInfo.lsrmux;
                SRMODE = cell->sliceInfo.srmode;
            } else {
                if (cell->sliceInfo.clk_sig != clk_sig)
                    return false;
                if (cell->sliceInfo.lsr_sig != lsr_sig)
                    return false;
                if (cell->sliceInfo.clkmux != CLKMUX)
                    return false;
                if (cell->sliceInfo.lsrmux != LSRMUX)
                    return false;
                if (cell->sliceInfo.srmode != SRMODE)
                    return false;
            }
            first = false;
        }
    }
    return true;
}

bool Arch::isBelLocationValid(BelId bel) const
{
    if (getBelType(bel) == id_TRELLIS_SLICE) {
        std::vector<const CellInfo *> bel_cells;
        Loc bel_loc = getBelLocation(bel);
        for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
            CellInfo *cell_other = getBoundBelCell(bel_other);
            if (cell_other != nullptr) {
                bel_cells.push_back(cell_other);
            }
        }
        if (getBoundBelCell(bel) != nullptr && getBoundBelCell(bel)->sliceInfo.has_l6mux && ((bel_loc.z % 2) == 1))
            return false;
        return slicesCompatible(bel_cells);
    } else {
        CellInfo *cell = getBoundBelCell(bel);
        if (cell == nullptr)
            return true;
        else
            return isValidBelForCell(cell, bel);
    }
}

bool Arch::isValidBelForCell(CellInfo *cell, BelId bel) const
{
    if (cell->type == id_TRELLIS_SLICE) {
        NPNR_ASSERT(getBelType(bel) == id_TRELLIS_SLICE);

        std::vector<const CellInfo *> bel_cells;
        Loc bel_loc = getBelLocation(bel);

        if (cell->sliceInfo.has_l6mux && ((bel_loc.z % 2) == 1))
            return false;

        for (auto bel_other : getBelsByTile(bel_loc.x, bel_loc.y)) {
            CellInfo *cell_other = getBoundBelCell(bel_other);
            if (cell_other != nullptr && bel_other != bel) {
                bel_cells.push_back(cell_other);
            }
        }

        bel_cells.push_back(cell);
        return slicesCompatible(bel_cells);
    } else if (cell->type == id_DCUA || cell->type == id_EXTREFB || cell->type == id_PCSCLKDIV) {
        return args.type != ArchArgs::LFE5U_25F && args.type != ArchArgs::LFE5U_45F && args.type != ArchArgs::LFE5U_85F;
    } else {
        // other checks
        return true;
    }
}

void Arch::permute_luts()
{
    NetCriticalityMap nc;
    get_criticalities(getCtx(), &nc);

    std::unordered_map<PortInfo *, size_t> port_to_user;
    for (auto net : sorted(nets)) {
        NetInfo *ni = net.second;
        for (size_t i = 0; i < ni->users.size(); i++) {
            auto &usr = ni->users.at(i);
            port_to_user[&(usr.cell->ports.at(usr.port))] = i;
        }
    }

    auto proc_lut = [&](CellInfo *ci, int lut) {
        std::vector<IdString> port_names;
        for (int i = 0; i < 4; i++)
            port_names.push_back(id(std::string("ABCD").substr(i, 1) + std::to_string(lut)));

        std::vector<std::pair<float, int>> inputs;
        std::vector<NetInfo *> orig_nets;

        for (int i = 0; i < 4; i++) {
            if (!ci->ports.count(port_names.at(i))) {
                ci->ports[port_names.at(i)].name = port_names.at(i);
                ci->ports[port_names.at(i)].type = PORT_IN;
            }
            auto &port = ci->ports.at(port_names.at(i));
            float crit = 0;
            if (port.net != nullptr && nc.count(port.net->name)) {
                auto &n = nc.at(port.net->name);
                size_t usr = port_to_user.at(&port);
                if (usr < n.criticality.size())
                    crit = n.criticality.at(usr);
            }
            orig_nets.push_back(port.net);
            inputs.emplace_back(crit, i);
        }
        // Least critical first (A input is slowest)

        // Avoid permuting locked LUTs (e.g. from an OOC submodule)
        if (ci->belStrength <= STRENGTH_STRONG)
            std::sort(inputs.begin(), inputs.end());
        for (int i = 0; i < 4; i++) {
            IdString p = port_names.at(i);
            // log_info("%s %s %f\n", p.c_str(ctx), port_names.at(inputs.at(i).second).c_str(ctx), inputs.at(i).first);
            disconnect_port(getCtx(), ci, p);
            ci->ports.at(p).net = nullptr;
            if (orig_nets.at(inputs.at(i).second) != nullptr) {
                connect_port(getCtx(), orig_nets.at(inputs.at(i).second), ci, p);
                ci->params[id(p.str(this) + "MUX")] = p.str(this);
            } else {
                ci->params[id(p.str(this) + "MUX")] = std::string("1");
            }
        }
        // Rewrite function
        int old_init = int_or_default(ci->params, id("LUT" + std::to_string(lut) + "_INITVAL"), 0);
        int new_init = 0;
        for (int i = 0; i < 16; i++) {
            int old_index = 0;
            for (int k = 0; k < 4; k++) {
                if (i & (1 << k))
                    old_index |= (1 << inputs.at(k).second);
            }
            if (old_init & (1 << old_index))
                new_init |= (1 << i);
        }
        ci->params[id("LUT" + std::to_string(lut) + "_INITVAL")] = Property(new_init, 16);
    };

    for (auto cell : sorted(cells)) {
        CellInfo *ci = cell.second;
        if (ci->type == id_TRELLIS_SLICE && str_or_default(ci->params, id("MODE"), "LOGIC") == "LOGIC") {
            proc_lut(ci, 0);
            proc_lut(ci, 1);
        }
    }
}

NEXTPNR_NAMESPACE_END
<|endoftext|>