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

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkReadWriteImageWithDictionaryTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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.

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

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkIOCommon.h"
#include "itkMetaDataObject.h"
#include "itkSpatialOrientationAdapter.h"

int itkReadWriteImageWithDictionaryTest(int argc, char* argv[])
{
  if( argc != 2 )
    {
    std::cerr << "Usage: " << argv[0] << " Input\n";
    return EXIT_FAILURE;
    }

  typedef itk::Image< unsigned char, 3 > ImageType;
  typedef itk::ImageFileReader< ImageType > ReaderType;
  typedef itk::ImageFileWriter< ImageType > WriterType;

  //Create the 16x16 input image
  ImageType::Pointer  inputImage = ImageType::New();

  ImageType::SizeType size;
  size.Fill( 16 );
  ImageType::IndexType index;
  index.Fill( 0 );
  ImageType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );
  inputImage->SetRegions( region );
  inputImage->Allocate();
  inputImage->FillBuffer( 0 );

  inputImage->SetDirection(
     itk::SpatialOrientationAdapter().ToDirectionCosines(
        itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP ) );

  // Add some metadata in the dictionary
  itk::MetaDataDictionary & inputDictionary = inputImage->GetMetaDataDictionary();
  std::string voxelunitstr = "mm. "; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_VoxelUnits,voxelunitstr);
  std::string datestr = "26-05-2010"; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_ExperimentDate,datestr );
  std::string timestr = "13-44-00.0"; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_ExperimentTime,timestr );
  std::string patientstr = "patientid "; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_PatientID,patientstr );

  // Write the image down
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput(inputImage);
  writer->SetFileName(argv[1]);
  writer->Update();

  // Read the image back
  ReaderType::Pointer reader = ReaderType::New();

  reader->SetFileName(argv[1]);
  reader->Update();

  ImageType::Pointer outputImage = reader->GetOutput();

  // Compare the metadatas
  int numMissingMetaData = 0;
  int numWrongMetaData = 0;

  itk::MetaDataDictionary & outputDictionary = outputImage->GetMetaDataDictionary();

  std::string metadatastr;

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_VoxelUnits, metadatastr ) )
    {
      // MetaIO is rather strict on the format of ITK_VoxelUnits but for our purpose "mm"=="mm. "
      if ( !( metadatastr==voxelunitstr || (metadatastr=="mm" && voxelunitstr=="mm. ") ) )
      {
      std::cout<<"voxelunitstr.size()="<<voxelunitstr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"voxelunitstr=|"<<voxelunitstr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_VoxelUnits"<<std::endl;
    ++numMissingMetaData;
    }

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_ExperimentDate, metadatastr ) )
    {
      if ( metadatastr != datestr )
      {
      std::cout<<"datestr.size()="<<datestr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"datestr=|"<<datestr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_ExperimentDate"<<std::endl;
    ++numMissingMetaData;
    }

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_ExperimentTime, metadatastr ) )
    {
      if ( metadatastr != timestr )
      {
      std::cout<<"timestr.size()="<<timestr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"timestr=|"<<timestr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_ExperimentTime"<<std::endl;
    ++numMissingMetaData;
    }

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_PatientID, metadatastr ) )
    {
      if ( metadatastr != patientstr )
      {
      std::cout<<"patientstr.size()="<<patientstr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"patientstr=|"<<patientstr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_PatientID"<<std::endl;
    ++numMissingMetaData;
    }

  std::cout<<std::endl<<"Number of missing metadata = "<<numMissingMetaData<<std::endl;
  std::cout<<"Number of wrong metadata = "<<numWrongMetaData<<std::endl<<std::endl;

  // Perform a weaker but more exhaustive test
  int numMissingMetaData2 = 0;
  int numWrongMetaData2 = 0;
  int numAddedMetaData2 = 0;

  for ( itk::MetaDataDictionary::ConstIterator it = inputDictionary.Begin();
        it != inputDictionary.End(); ++it )
    {
    if ( !outputDictionary.HasKey( it->first ) )
      {
      std::cout<<"Missing "<<it->first<<std::endl;
      ++numMissingMetaData2;
      }
    else
      {
      itk::MetaDataDictionary::ConstIterator it2 = outputDictionary.Find( it->first );
      if ( it->second->GetMetaDataObjectTypeInfo() != it2->second->GetMetaDataObjectTypeInfo() )
        {
        std::cout<<"input_meta="<<it->second;
        std::cout<<"output_meta="<<it2->second;
        ++numWrongMetaData2;
        }
      }
    }

  for ( itk::MetaDataDictionary::ConstIterator it = outputDictionary.Begin();
        it != outputDictionary.End(); ++it )
    {
    if ( !inputDictionary.HasKey( it->first ) )
      {
      std::cout<<"added_meta=|"<<it->first<<"|-"<<it->second;
      ++numAddedMetaData2;
      }
    }

  std::cout<<std::endl<<"(weak but exhaustive) Number of missing metadata = "<<numMissingMetaData2<<std::endl;
  std::cout<<"(weak but exhaustive) Number of wrong metadata = "<<numWrongMetaData2<<std::endl;
  std::cout<<"(weak but exhaustive) Number of added metadata = "<<numAddedMetaData2<<std::endl<<std::endl;

  // Do not consider added metadata as errors since this may just indicate file format information
  if ( numMissingMetaData!=0 || numWrongMetaData!=0 ||
       numMissingMetaData2!=0 || numWrongMetaData2!=0 )
    {
    // FIXME:   FIXME MetaImage library: Then restore this test:    return EXIT_FAILURE;
    std::cout <<" FAILED: FIXME MetaImage library: Then restore this test" << std::endl;
    }

  return EXIT_SUCCESS;
}
<commit_msg>COMP: For Visual Studio 6, the map iterator cannot be safely used outside the DLL that contains the map. The part of the test that uses the MetaDataDictionary is removed for VS6, shared builds.<commit_after>/*=========================================================================

Program:   Insight Segmentation & Registration Toolkit
Module:    itkReadWriteImageWithDictionaryTest.cxx
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm 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.

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

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkIOCommon.h"
#include "itkMetaDataObject.h"
#include "itkSpatialOrientationAdapter.h"

int itkReadWriteImageWithDictionaryTest(int argc, char* argv[])
{
  if( argc != 2 )
    {
    std::cerr << "Usage: " << argv[0] << " Input\n";
    return EXIT_FAILURE;
    }

  typedef itk::Image< unsigned char, 3 > ImageType;
  typedef itk::ImageFileReader< ImageType > ReaderType;
  typedef itk::ImageFileWriter< ImageType > WriterType;

  //Create the 16x16 input image
  ImageType::Pointer  inputImage = ImageType::New();

  ImageType::SizeType size;
  size.Fill( 16 );
  ImageType::IndexType index;
  index.Fill( 0 );
  ImageType::RegionType region;
  region.SetSize( size );
  region.SetIndex( index );
  inputImage->SetRegions( region );
  inputImage->Allocate();
  inputImage->FillBuffer( 0 );

  inputImage->SetDirection(
    itk::SpatialOrientationAdapter().ToDirectionCosines(
      itk::SpatialOrientation::ITK_COORDINATE_ORIENTATION_RIP ) );

  // Add some metadata in the dictionary
  itk::MetaDataDictionary & inputDictionary =
    inputImage->GetMetaDataDictionary();
  std::string voxelunitstr = "mm. "; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_VoxelUnits,voxelunitstr);
  std::string datestr = "26-05-2010"; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_ExperimentDate,datestr );
  std::string timestr = "13-44-00.0"; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_ExperimentTime,timestr );
  std::string patientstr = "patientid "; // try to follow analyze format (length matters)
  itk::EncapsulateMetaData<std::string>(inputDictionary,itk::ITK_PatientID,patientstr );

  // Write the image down
  WriterType::Pointer writer = WriterType::New();

  writer->SetInput(inputImage);
  writer->SetFileName(argv[1]);
  writer->Update();

  // Read the image back
  ReaderType::Pointer reader = ReaderType::New();

  reader->SetFileName(argv[1]);
  reader->Update();

  ImageType::Pointer outputImage = reader->GetOutput();

  // Compare the metadatas
  int numMissingMetaData = 0;
  int numWrongMetaData = 0;

  itk::MetaDataDictionary & outputDictionary =
    outputImage->GetMetaDataDictionary();

  std::string metadatastr;

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_VoxelUnits, metadatastr ) )
    {
    // MetaIO is rather strict on the format of ITK_VoxelUnits but for our purpose "mm"=="mm. "
    if ( !( metadatastr==voxelunitstr || (metadatastr=="mm" && voxelunitstr=="mm. ") ) )
      {
      std::cout<<"voxelunitstr.size()="<<voxelunitstr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"voxelunitstr=|"<<voxelunitstr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_VoxelUnits"<<std::endl;
    ++numMissingMetaData;
    }

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_ExperimentDate, metadatastr ) )
    {
    if ( metadatastr != datestr )
      {
      std::cout<<"datestr.size()="<<datestr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"datestr=|"<<datestr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_ExperimentDate"<<std::endl;
    ++numMissingMetaData;
    }

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_ExperimentTime, metadatastr ) )
    {
    if ( metadatastr != timestr )
      {
      std::cout<<"timestr.size()="<<timestr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"timestr=|"<<timestr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_ExperimentTime"<<std::endl;
    ++numMissingMetaData;
    }

  if ( itk::ExposeMetaData<std::string>( outputDictionary, itk::ITK_PatientID, metadatastr ) )
    {
    if ( metadatastr != patientstr )
      {
      std::cout<<"patientstr.size()="<<patientstr.size()<<std::endl;
      std::cout<<"metadatastr.size()="<<metadatastr.size()<<std::endl;
      std::cout<<"patientstr=|"<<patientstr<<"|"<<std::endl;
      std::cout<<"metadatastr=|"<<metadatastr<<"|"<<std::endl;
      ++numWrongMetaData;
      }
    }
  else
    {
    std::cout<<"Missing ITK_PatientID"<<std::endl;
    ++numMissingMetaData;
    }

  std::cout<<std::endl<<"Number of missing metadata = "<<numMissingMetaData<<std::endl;
  std::cout<<"Number of wrong metadata = "<<numWrongMetaData<<std::endl<<std::endl;

  /** the visual studio 6 compiler cannot dereference iterator outside
   * of the dll */
#if defined(_MSC_VER) && (_MSC_VER <= 1300) && !defined(ITKSTATIC)
  return EXIT_SUCCESS;
#else
  // Perform a weaker but more exhaustive test
  int numMissingMetaData2 = 0;
  int numWrongMetaData2 = 0;
  int numAddedMetaData2 = 0;

  for ( itk::MetaDataDictionary::ConstIterator it = inputDictionary.Begin();
        it != inputDictionary.End(); ++it )
    {
    if ( !outputDictionary.HasKey( it->first ) )
      {
      std::cout<<"Missing "<<it->first<<std::endl;
      ++numMissingMetaData2;
      }
    else
      {
      itk::MetaDataDictionary::ConstIterator it2 = outputDictionary.Find( it->first );
      if ( it->second->GetMetaDataObjectTypeInfo() != it2->second->GetMetaDataObjectTypeInfo() )
        {
        std::cout<<"input_meta="<<it->second;
        std::cout<<"output_meta="<<it2->second;
        ++numWrongMetaData2;
        }
      }
    }

  for ( itk::MetaDataDictionary::ConstIterator it = outputDictionary.Begin();
        it != outputDictionary.End(); ++it )
    {
    if ( !inputDictionary.HasKey( it->first ) )
      {
      std::cout<<"added_meta=|"<<it->first<<"|-"<<it->second;
      ++numAddedMetaData2;
      }
    }

  std::cout<<std::endl<<"(weak but exhaustive) Number of missing metadata = "<<numMissingMetaData2<<std::endl;
  std::cout<<"(weak but exhaustive) Number of wrong metadata = "<<numWrongMetaData2<<std::endl;
  std::cout<<"(weak but exhaustive) Number of added metadata = "<<numAddedMetaData2<<std::endl<<std::endl;

  // Do not consider added metadata as errors since this may just indicate file format information
  if ( numMissingMetaData!=0 || numWrongMetaData!=0 ||
       numMissingMetaData2!=0 || numWrongMetaData2!=0 )
    {
    // FIXME:   FIXME MetaImage library: Then restore this test:    return EXIT_FAILURE;
    std::cout <<" FAILED: FIXME MetaImage library: Then restore this test" << std::endl;
    }

  return EXIT_SUCCESS;
#endif
}
<|endoftext|>


<commit_before>#include "../../Interface/Server.h"
#include "../../Interface/Database.h"
#include "../database.h"

void open_server_database(bool &use_berkeleydb, bool init_db);

const DATABASE_ID URBACKUPDB_SERVER_SETTINGS=30;

void open_settings_database_full(bool use_berkeleydb)
{
	if(!use_berkeleydb)
	{
		if(! Server->openDatabase("urbackup/backup_server_settings.db", URBACKUPDB_SERVER_SETTINGS, "sqlite") )
		{
			Server->Log("Couldn't open Database backup_server_settings.db", LL_ERROR);
			return;
		}
	}
	else
	{
		if(! Server->openDatabase("urbackup/backup_server_settings.bdb", URBACKUPDB_SERVER_SETTINGS, "bdb") )
		{
			Server->Log("Couldn't open Database backup_server_settings.bdb", LL_ERROR);
			return;
		}
	}
}

int repair_cmd(void)
{
	bool use_berkeleydb;
	open_server_database(use_berkeleydb, true);
	open_settings_database_full(use_berkeleydb);

	IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
	if(db==NULL)
	{
		Server->Log("Could not open main database", LL_ERROR);
		return 1;
	}

	Server->Log("Exporting main database...", LL_INFO);
	if(!db->Dump("urbackup/server_database_export_main.sql"))
	{
		Server->Log("Exporting main database failed", LL_ERROR);
		return 1;
	}

	IDatabase *db_settings=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER_SETTINGS);
	if(db_settings==NULL)
	{
		Server->Log("Could not open settings database", LL_ERROR);
		return 1;
	}

	Server->Log("Exporting settings database...", LL_INFO);
	if(!db_settings->Dump("urbackup/server_database_export_settings.sql"))
	{
		Server->Log("Exporting settings database failed", LL_ERROR);
		return 1;
	}

	Server->destroyAllDatabases();
	db=NULL;

	Server->deleteFile("urbackup/backup_server.db");
	Server->deleteFile("urbackup/backup_server.db-wal");
	Server->deleteFile("urbackup/backup_server.db-shm");

	Server->deleteFile("urbackup/backup_server_settings.db");
	Server->deleteFile("urbackup/backup_server_settings.db-wal");
	Server->deleteFile("urbackup/backup_server_settings.db-shm");

	open_server_database(use_berkeleydb, false);
	open_settings_database_full(use_berkeleydb);

	db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
	if(db==NULL)
	{
		Server->Log("Could not open main database", LL_ERROR);
		return 1;
	}

	Server->Log("Importing main database...", LL_INFO);
	if(!db->Import("urbackup/server_database_export_main.sql"))
	{
		Server->Log("Importing main database failed", LL_ERROR);
		return 1;
	}

	db_settings=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER_SETTINGS);
	if(db_settings==NULL)
	{
		Server->Log("Could not open settings database", LL_ERROR);
		return 1;
	}

	Server->Log("Importing settings database...", LL_INFO);
	if(!db_settings->Import("urbackup/server_database_export_settings.sql"))
	{
		Server->Log("Importing settings database failed", LL_ERROR);
		return 1;
	}

	Server->deleteFile("urbackup/server_database_export_main.sql");
	Server->deleteFile("urbackup/server_database_export_settings.sql");

	Server->Log("Completed sucessfully.", LL_INFO);

	return 0;
}<commit_msg>Added command to repair database -- removed second open<commit_after>#include "../../Interface/Server.h"
#include "../../Interface/Database.h"
#include "../database.h"

void open_server_database(bool &use_berkeleydb, bool init_db);

const DATABASE_ID URBACKUPDB_SERVER_SETTINGS=30;

void open_settings_database_full(bool use_berkeleydb)
{
	if(!use_berkeleydb)
	{
		if(! Server->openDatabase("urbackup/backup_server_settings.db", URBACKUPDB_SERVER_SETTINGS, "sqlite") )
		{
			Server->Log("Couldn't open Database backup_server_settings.db", LL_ERROR);
			return;
		}
	}
	else
	{
		if(! Server->openDatabase("urbackup/backup_server_settings.bdb", URBACKUPDB_SERVER_SETTINGS, "bdb") )
		{
			Server->Log("Couldn't open Database backup_server_settings.bdb", LL_ERROR);
			return;
		}
	}
}

int repair_cmd(void)
{
	bool use_berkeleydb;
	open_server_database(use_berkeleydb, true);
	open_settings_database_full(use_berkeleydb);

	IDatabase *db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
	if(db==NULL)
	{
		Server->Log("Could not open main database", LL_ERROR);
		return 1;
	}

	Server->Log("Exporting main database...", LL_INFO);
	if(!db->Dump("urbackup/server_database_export_main.sql"))
	{
		Server->Log("Exporting main database failed", LL_ERROR);
		return 1;
	}

	IDatabase *db_settings=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER_SETTINGS);
	if(db_settings==NULL)
	{
		Server->Log("Could not open settings database", LL_ERROR);
		return 1;
	}

	Server->Log("Exporting settings database...", LL_INFO);
	if(!db_settings->Dump("urbackup/server_database_export_settings.sql"))
	{
		Server->Log("Exporting settings database failed", LL_ERROR);
		return 1;
	}

	Server->destroyAllDatabases();
	db=NULL;

	Server->deleteFile("urbackup/backup_server.db");
	Server->deleteFile("urbackup/backup_server.db-wal");
	Server->deleteFile("urbackup/backup_server.db-shm");

	Server->deleteFile("urbackup/backup_server_settings.db");
	Server->deleteFile("urbackup/backup_server_settings.db-wal");
	Server->deleteFile("urbackup/backup_server_settings.db-shm");

	db=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER);
	if(db==NULL)
	{
		Server->Log("Could not open main database", LL_ERROR);
		return 1;
	}

	Server->Log("Importing main database...", LL_INFO);
	if(!db->Import("urbackup/server_database_export_main.sql"))
	{
		Server->Log("Importing main database failed", LL_ERROR);
		return 1;
	}

	db_settings=Server->getDatabase(Server->getThreadID(), URBACKUPDB_SERVER_SETTINGS);
	if(db_settings==NULL)
	{
		Server->Log("Could not open settings database", LL_ERROR);
		return 1;
	}

	Server->Log("Importing settings database...", LL_INFO);
	if(!db_settings->Import("urbackup/server_database_export_settings.sql"))
	{
		Server->Log("Importing settings database failed", LL_ERROR);
		return 1;
	}

	Server->deleteFile("urbackup/server_database_export_main.sql");
	Server->deleteFile("urbackup/server_database_export_settings.sql");

	Server->Log("Completed sucessfully.", LL_INFO);

	return 0;
}<|endoftext|>


<commit_before><commit_msg>SPD(N) class bugfixes<commit_after><|endoftext|>


<commit_before>/************************************************************************/
/*                                                                      */
/*                 Copyright 2009 by Ullrich Koethe                     */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#define PY_ARRAY_UNIQUE_SYMBOL vigranumpytest_PyArray_API
#include <Python.h>
#include <boost/python.hpp>
#include <vigra/numpy_array.hxx>
#include <vigra/multi_array.hxx>
#include <vigra/numpy_array_converters.hxx>
#include <vigra/fftw3.hxx>
#include <vigra/gaborfilter.hxx>
#include <iostream>

namespace vigra {

template <>
struct NumpyArrayValuetypeTraits<FFTWComplex>
{
    static bool isValuetypeCompatible(PyArrayObject const * obj) /* obj must not be NULL */
    {
        return PyArray_EquivTypenums(NPY_CDOUBLE, PyArray_DESCR((PyObject *)obj)->type_num) &&
               PyArray_ITEMSIZE((PyObject *)obj) == sizeof(FFTWComplex);
    }

    static NPY_TYPES const typeCode = NPY_CDOUBLE;

    static std::string typeName()
    {
        return "complex128";
    }

    static std::string typeNameImpex()
    {
        return "";
    }

    static PyObject * typeObject()
    {
        return PyArray_TypeObjectFromType(NPY_CDOUBLE);
    }
};

template <class T>
NumpyAnyArray
pythonCreateGaborFilter(typename MultiArrayView<2,T>::difference_type shape,
                        double orientation, double centerFrequency,
                        double angularSigma, double radialSigma, NumpyArray<2,Singleband<T> > res)
{
    res.reshapeIfEmpty(shape, "createGaborFilter(): Output array has wrong shape.");

    createGaborFilter(destImageRange(res),
                      orientation, centerFrequency, angularSigma, radialSigma);
    return res;
}

template <unsigned int N, int SIGN>
NumpyAnyArray
pythonFourierTransform(NumpyArray<N, Multiband<FFTWComplex> > in, NumpyArray<N, Multiband<FFTWComplex> > res)
{
    res.reshapeIfEmpty(in.shape(), in.strideOrdering(),
        "fourierTransform(): Output array must have the same shape and stride ordering as input array.", true);

    for(MultiArrayIndex k=0; k<in.shape(N-1); ++k)
    {
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bin = in.bindOuter(k).permuteStridesDescending();
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bres = res.bindOuter(k).permuteStridesDescending();

        TinyVector<int, N-1> bshape(bin.shape()), itotal(bin.shape()), ototal(bres.shape());
        double norm = (double)bshape[0];
        for(int j=1; j<N-1; ++j)
        {
            itotal[j] = bin.stride(j-1) / bin.stride(j);
            ototal[j] = bres.stride(j-1) / bres.stride(j);
            norm *= (double)bshape[j];
        }

        fftw_plan plan = fftw_plan_many_dft(N-1, bshape.begin(), 1,
                                            (fftw_complex*)bin.data(), itotal.begin(),
                                            bin.stride(N-2), 0,
                                            (fftw_complex*)bres.data(), ototal.begin(),
                                            bres.stride(N-2), 0,
                                            SIGN, FFTW_ESTIMATE);
        vigra_postcondition(plan != 0, "fourierTransform(): Unable to create plan.");
        fftw_execute(plan);
        fftw_destroy_plan(plan);
        if(SIGN == FFTW_BACKWARD)
        {
            bres *= FFTWComplex(1.0 / norm);
        }
    }
    return res;
}

NumpyAnyArray
pythonFourierTransformR2C(NumpyAnyArray in, NumpyAnyArray res)
{
    switch(in.spatialDimensions())
    {
      case 2:
      {
        NumpyArray<3, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<3, FFTW_FORWARD>(inc, out);
      }
      case 3:
      {
        NumpyArray<4, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<4, FFTW_FORWARD>(inc, out);
      }
      default:
        vigra_fail("fourierTransform(): "
                   "Can only handle 2 or 3 spatial dimensions.");
    }
    return res; // this will never be reached
}

} // namespace vigra

using namespace boost::python;
using namespace vigra;

BOOST_PYTHON_MODULE_INIT(fourier)
{
    import_vigranumpy();

    docstring_options doc_options(true, true, false);

    def("fourierTransform", registerConverters(&pythonFourierTransformR2C),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional or 3-dimensional Fourier transformation of a scalar float64 array."
        "If the input array has multiple channels, each channel is transformed separately.\n"
        );

    def("fourierTransform", registerConverters(&pythonFourierTransform<3, FFTW_FORWARD>),
        (arg("image"), arg("out") = object()),
        "Likewise for a 2D complex128 image.\n");

    def("fourierTransform", registerConverters(&pythonFourierTransform<4, FFTW_FORWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<3, FFTW_BACKWARD>),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional inverse Fourier transformation of a complex array."
        "If the input array has multiple channels, each channel is transformed separately.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<4, FFTW_BACKWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("createGaborFilter", registerConverters(&pythonCreateGaborFilter<float>),
        (arg("shape"),arg("orientation"),arg("centerFrequency"),arg("angularSigma"),arg("radialSigma"), arg("out") = object()),
        "Create a 2-dimensional gabor filter in frequency space.");

    def("radialGaborSigma", &radialGaborSigma,
        "Calculate sensible radial sigma for given parameters.");

    def("angularGaborSigma", &angularGaborSigma,
        "Calculate sensible angular sigma for given parameters.");
}
<commit_msg>renamed PY_ARRAY_UNIQUE_SYMBOL in vigranumpy.fourier<commit_after>/************************************************************************/
/*                                                                      */
/*                 Copyright 2009 by Ullrich Koethe                     */
/*                                                                      */
/*    This file is part of the VIGRA computer vision library.           */
/*    The VIGRA Website is                                              */
/*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
/*    Please direct questions, bug reports, and contributions to        */
/*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
/*        vigra@informatik.uni-hamburg.de                               */
/*                                                                      */
/*    Permission is hereby granted, free of charge, to any person       */
/*    obtaining a copy of this software and associated documentation    */
/*    files (the "Software"), to deal in the Software without           */
/*    restriction, including without limitation the rights to use,      */
/*    copy, modify, merge, publish, distribute, sublicense, and/or      */
/*    sell copies of the Software, and to permit persons to whom the    */
/*    Software is furnished to do so, subject to the following          */
/*    conditions:                                                       */
/*                                                                      */
/*    The above copyright notice and this permission notice shall be    */
/*    included in all copies or substantial portions of the             */
/*    Software.                                                         */
/*                                                                      */
/*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
/*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
/*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
/*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
/*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
/*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
/*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
/*    OTHER DEALINGS IN THE SOFTWARE.                                   */
/*                                                                      */
/************************************************************************/

#define PY_ARRAY_UNIQUE_SYMBOL vigranumpyfourier_PyArray_API
#include <Python.h>
#include <boost/python.hpp>
#include <vigra/numpy_array.hxx>
#include <vigra/multi_array.hxx>
#include <vigra/numpy_array_converters.hxx>
#include <vigra/fftw3.hxx>
#include <vigra/gaborfilter.hxx>
#include <iostream>

namespace vigra {

template <>
struct NumpyArrayValuetypeTraits<FFTWComplex>
{
    static bool isValuetypeCompatible(PyArrayObject const * obj) /* obj must not be NULL */
    {
        return PyArray_EquivTypenums(NPY_CDOUBLE, PyArray_DESCR((PyObject *)obj)->type_num) &&
               PyArray_ITEMSIZE((PyObject *)obj) == sizeof(FFTWComplex);
    }

    static NPY_TYPES const typeCode = NPY_CDOUBLE;

    static std::string typeName()
    {
        return "complex128";
    }

    static std::string typeNameImpex()
    {
        return "";
    }

    static PyObject * typeObject()
    {
        return PyArray_TypeObjectFromType(NPY_CDOUBLE);
    }
};

template <class T>
NumpyAnyArray
pythonCreateGaborFilter(typename MultiArrayView<2,T>::difference_type shape,
                        double orientation, double centerFrequency,
                        double angularSigma, double radialSigma, NumpyArray<2,Singleband<T> > res)
{
    res.reshapeIfEmpty(shape, "createGaborFilter(): Output array has wrong shape.");

    createGaborFilter(destImageRange(res),
                      orientation, centerFrequency, angularSigma, radialSigma);
    return res;
}

template <unsigned int N, int SIGN>
NumpyAnyArray
pythonFourierTransform(NumpyArray<N, Multiband<FFTWComplex> > in, NumpyArray<N, Multiband<FFTWComplex> > res)
{
    res.reshapeIfEmpty(in.shape(), in.strideOrdering(),
        "fourierTransform(): Output array must have the same shape and stride ordering as input array.", true);

    for(MultiArrayIndex k=0; k<in.shape(N-1); ++k)
    {
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bin = in.bindOuter(k).permuteStridesDescending();
        MultiArrayView<N-1, FFTWComplex, StridedArrayTag> bres = res.bindOuter(k).permuteStridesDescending();

        TinyVector<int, N-1> bshape(bin.shape()), itotal(bin.shape()), ototal(bres.shape());
        double norm = (double)bshape[0];
        for(int j=1; j<N-1; ++j)
        {
            itotal[j] = bin.stride(j-1) / bin.stride(j);
            ototal[j] = bres.stride(j-1) / bres.stride(j);
            norm *= (double)bshape[j];
        }

        fftw_plan plan = fftw_plan_many_dft(N-1, bshape.begin(), 1,
                                            (fftw_complex*)bin.data(), itotal.begin(),
                                            bin.stride(N-2), 0,
                                            (fftw_complex*)bres.data(), ototal.begin(),
                                            bres.stride(N-2), 0,
                                            SIGN, FFTW_ESTIMATE);
        vigra_postcondition(plan != 0, "fourierTransform(): Unable to create plan.");
        fftw_execute(plan);
        fftw_destroy_plan(plan);
        if(SIGN == FFTW_BACKWARD)
        {
            bres *= FFTWComplex(1.0 / norm);
        }
    }
    return res;
}

NumpyAnyArray
pythonFourierTransformR2C(NumpyAnyArray in, NumpyAnyArray res)
{
    switch(in.spatialDimensions())
    {
      case 2:
      {
        NumpyArray<3, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<3, FFTW_FORWARD>(inc, out);
      }
      case 3:
      {
        NumpyArray<4, Multiband<FFTWComplex> > inc(in, true), out(res, false);
        return pythonFourierTransform<4, FFTW_FORWARD>(inc, out);
      }
      default:
        vigra_fail("fourierTransform(): "
                   "Can only handle 2 or 3 spatial dimensions.");
    }
    return res; // this will never be reached
}

} // namespace vigra

using namespace boost::python;
using namespace vigra;

BOOST_PYTHON_MODULE_INIT(fourier)
{
    import_vigranumpy();

    docstring_options doc_options(true, true, false);

    def("fourierTransform", registerConverters(&pythonFourierTransformR2C),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional or 3-dimensional Fourier transformation of a scalar float64 array."
        "If the input array has multiple channels, each channel is transformed separately.\n"
        );

    def("fourierTransform", registerConverters(&pythonFourierTransform<3, FFTW_FORWARD>),
        (arg("image"), arg("out") = object()),
        "Likewise for a 2D complex128 image.\n");

    def("fourierTransform", registerConverters(&pythonFourierTransform<4, FFTW_FORWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<3, FFTW_BACKWARD>),
        (arg("image"), arg("out") = object()),
        "Perform 2-dimensional inverse Fourier transformation of a complex array."
        "If the input array has multiple channels, each channel is transformed separately.\n");

    def("fourierTransformInverse", registerConverters(&pythonFourierTransform<4, FFTW_BACKWARD>),
        (arg("volume"), arg("out") = object()),
        "Likewise for a 3D complex128 volume.\n");

    def("createGaborFilter", registerConverters(&pythonCreateGaborFilter<float>),
        (arg("shape"),arg("orientation"),arg("centerFrequency"),arg("angularSigma"),arg("radialSigma"), arg("out") = object()),
        "Create a 2-dimensional gabor filter in frequency space.");

    def("radialGaborSigma", &radialGaborSigma,
        "Calculate sensible radial sigma for given parameters.");

    def("angularGaborSigma", &angularGaborSigma,
        "Calculate sensible angular sigma for given parameters.");
}
<|endoftext|>


<commit_before>/*----------------------------------------------------------------------------------*\
 |																					|
 | rcb_fast_generator.hpp 															|
 |																					|
 | Copyright (c) 2020 Richard Cookman												|
 |																					|
 | Permission is hereby granted, free of charge, to any person obtaining a copy		|
 | of this software and associated documentation files (the "Software"), to deal	|
 | in the Software without restriction, including without limitation the rights		|
 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell		|
 | copies of the Software, and to permit persons to whom the Software is			|
 | furnished to do so, subject to the following conditions:							|
 |																					|
 | The above copyright notice and this permission notice shall be included in all	|
 | copies or substantial portions of the Software.									|
 |																					|
 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR		|
 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,			|
 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE		|
 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER			|
 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,	|
 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE	|
 | SOFTWARE.																		|
 |																					|
\*----------------------------------------------------------------------------------*/
#pragma once

#include "rcb_generator.hpp"

namespace rcbg {

template<typename T>
T circular_shift_right(T val, T count) {
	count %= sizeof(T) * 8;
	return (val << (sizeof(T) * 8) - count) | (val >> count);
}
template<typename T>
T circular_shift_left(T val, T count) {
	count %= sizeof(T) * 8;
	return (val << count) | (val >> (sizeof(T) * 8) - count);
}
template<typename T>
T get_one_bits(unsigned count) {
	//make a string of one bits
	T rtn = -1;
    return ~((T)-1 << count);
}

//the random cycle bit generator - random number generator
template<typename T,
		 unsigned CntN = sizeof(T)>
class rcb_fast_generator {
private:
	T val;
	rcb_generator_count<CntN> cnt;
	//only first one flags used (0 is whether reseed enabled)
	char flags;

	T generate(T val) {
		//take the lower count bits
		T tmp = ((val + ((val & get_one_bits<T>((sizeof(T)*8)/2 - 1)) << 1)) % ((sizeof(T)*8) - 1)) | 1;

		//circular shift by one to the right
		val ^= circular_shift_right(val, (T)1);

		val ^= val >> sizeof(T)*8 / 2;
		val ^= val << sizeof(T)*8 / 2;

		//circular shift by that many bits
		return val ^ circular_shift_right(val, tmp);
	}
	T generate_outer(T tmp_cnt) {
		T val2 = (~val << 1) * (generate(~val) << 1);
		return val = generate(val) ^ val2 ^ generate(val2) ^ generate(~generate(tmp_cnt));
	}
	void seed(T rnd, T offset, bool reseed) {
		flags = 0;
		val = ~(rnd + offset);
		flags = set_bit(flags, 0, reseed);
	}
public:
	rcb_fast_generator(T rnd, bool reseed = false) {
		seed(rnd, 10, reseed);
	}
	T rand() {
		bool gd = cnt.increment();
		T tmp_cnt = cnt;
		if(tmp_cnt == 0) ++tmp_cnt;
		T rtn = generate_outer(tmp_cnt);

		if(!gd && reseeds()) {
			T a = generate_outer(++tmp_cnt);
			T b = generate_outer(++tmp_cnt);
			seed(a, b, true);
		}
		return rtn;
	}
	bool good() const {
		return cnt.good();
	}
	bool reseeds() const {
		return get_bit(flags, 0);
	}
};

}
<commit_msg>optimisation<commit_after>/*----------------------------------------------------------------------------------*\
 |																					|
 | rcb_fast_generator.hpp 															|
 |																					|
 | Copyright (c) 2020 Richard Cookman												|
 |																					|
 | Permission is hereby granted, free of charge, to any person obtaining a copy		|
 | of this software and associated documentation files (the "Software"), to deal	|
 | in the Software without restriction, including without limitation the rights		|
 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell		|
 | copies of the Software, and to permit persons to whom the Software is			|
 | furnished to do so, subject to the following conditions:							|
 |																					|
 | The above copyright notice and this permission notice shall be included in all	|
 | copies or substantial portions of the Software.									|
 |																					|
 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR		|
 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,			|
 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE		|
 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER			|
 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,	|
 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE	|
 | SOFTWARE.																		|
 |																					|
\*----------------------------------------------------------------------------------*/
#pragma once

#include "rcb_generator.hpp"

namespace rcbg {

template<typename T>
T circular_shift_right(T val, T count) {
	count %= sizeof(T) * 8;
	return (val << (sizeof(T) * 8) - count) | (val >> count);
}
template<typename T>
T circular_shift_left(T val, T count) {
	count %= sizeof(T) * 8;
	return (val << count) | (val >> (sizeof(T) * 8) - count);
}
template<typename T>
T get_one_bits(unsigned count) {
	//make a string of one bits
    return ~((T)-1 << count);
}

//the random cycle bit generator - random number generator
template<typename T,
		 unsigned CntN = sizeof(T)>
class rcb_fast_generator {
private:
	T val;
	rcb_generator_count<CntN> cnt;
	//only first one flags used (0 is whether reseed enabled)
	char flags;

	T generate(T val) {
		//take the lower count bits
		T tmp = ((val + ((val & get_one_bits<T>((sizeof(T)*8)/2 - 1)) << 1)) % ((sizeof(T)*8) - 1)) | 1;

		//circular shift by one to the right
		val ^= circular_shift_right(val, (T)1);

		val ^= val >> sizeof(T)*8 / 2;
		val ^= val << sizeof(T)*8 / 2;

		//circular shift by that many bits
		return val ^ circular_shift_right(val, tmp);
	}
	T generate_outer(T tmp_cnt) {
		T val2 = (~val << 1) * (generate(~val) << 1);
		return val = generate(val) ^ val2 ^ generate(val2) ^ generate(~generate(tmp_cnt));
	}
	void seed(T rnd, T offset, bool reseed) {
		flags = 0;
		val = ~(rnd + offset);
		flags = set_bit(flags, 0, reseed);
	}
public:
	rcb_fast_generator(T rnd, bool reseed = false) {
		seed(rnd, 10, reseed);
	}
	T rand() {
		bool gd = cnt.increment();
		T tmp_cnt = cnt;
		if(tmp_cnt == 0) ++tmp_cnt;
		T rtn = generate_outer(tmp_cnt);

		if(!gd && reseeds()) {
			T a = generate_outer(++tmp_cnt);
			T b = generate_outer(++tmp_cnt);
			seed(a, b, true);
		}
		return rtn;
	}
	bool good() const {
		return cnt.good();
	}
	bool reseeds() const {
		return get_bit(flags, 0);
	}
};

}
<|endoftext|>


<commit_before>#include "stdafx.h"

#define LOGFILE_PATH "log.etl"

void ErrorExit(char* lpszFunction)
{
	// Retrieve the system error message for the last-error code

	LPVOID lpMsgBuf;
	DWORD dw = GetLastError();

	FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		dw,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPTSTR)&lpMsgBuf,
		0, NULL);

	// Display the error message and exit the process

	printf(
		"%s failed with error %d: %s\n",
		lpszFunction, dw, lpMsgBuf);
	ExitProcess(dw);
}

int _tmain(int argc, _TCHAR* argv[])
{
	ULONG status = ERROR_SUCCESS;
	TRACEHANDLE SessionHandle = 0;
	EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;
	ULONG BufferSize = 0;

	// Allocate memory for the session properties. The memory must
	// be large enough to include the log file name and session name,
	// which get appended to the end of the session properties structure.

	BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) + sizeof(KERNEL_LOGGER_NAME);
	pSessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(BufferSize);
	if (NULL == pSessionProperties)
	{
		wprintf(L"Unable to allocate %d bytes for properties structure.\n", BufferSize);
		goto cleanup;
	}

	// Set the session properties. You only append the log file name
	// to the properties structure; the StartTrace function appends
	// the session name for you.

	ZeroMemory(pSessionProperties, BufferSize);
	pSessionProperties->Wnode.BufferSize = BufferSize;
	pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
	pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
	pSessionProperties->Wnode.Guid = SystemTraceControlGuid;
	pSessionProperties->EnableFlags = EVENT_TRACE_FLAG_NETWORK_TCPIP;
	pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR;
	pSessionProperties->MaximumFileSize = 5;  // 5 MB
	pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
	pSessionProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(KERNEL_LOGGER_NAME);
	strcpy(((char*)pSessionProperties + pSessionProperties->LogFileNameOffset), LOGFILE_PATH);

	// Create the trace session.

	status = StartTrace((PTRACEHANDLE)&SessionHandle, KERNEL_LOGGER_NAME, pSessionProperties);

	if (ERROR_SUCCESS != status)
	{
		if (ERROR_ALREADY_EXISTS == status)
		{
			wprintf(L"The NT Kernel Logger session is already in use.\n");
		}
		else
		{
			ErrorExit("EnableTrace");
		}

		goto cleanup;
	}

	wprintf(L"Press any key to end trace session ");
	getchar();

cleanup:

	if (SessionHandle)
	{
		status = ControlTrace(SessionHandle, KERNEL_LOGGER_NAME, pSessionProperties, EVENT_TRACE_CONTROL_STOP);

		if (ERROR_SUCCESS != status)
		{
			ErrorExit("ControlTrace");
		}
	}

	if (pSessionProperties)
		free(pSessionProperties);
	return 0;
}

<commit_msg>clean<commit_after>#include "stdafx.h"

#define LOGFILE_PATH "log.etl"

void ErrorExit(char* lpszFunction)
{
	// Retrieve the system error message for the last-error code

	LPVOID lpMsgBuf;
	DWORD dw = GetLastError();

	FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		dw,
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPTSTR)&lpMsgBuf,
		0, NULL);

	// Display the error message and exit the process

	printf(
		"%s failed with error %d: %s\n",
		lpszFunction, dw, lpMsgBuf);
	ExitProcess(dw);
}

int _tmain(int argc, _TCHAR* argv[])
{
	ULONG status = ERROR_SUCCESS;
	TRACEHANDLE SessionHandle = 0;
	EVENT_TRACE_PROPERTIES* pSessionProperties = NULL;
	ULONG BufferSize = 0;

	// Allocate memory for the session properties. The memory must
	// be large enough to include the log file name and session name,
	// which get appended to the end of the session properties structure.

	BufferSize = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(LOGFILE_PATH) + sizeof(KERNEL_LOGGER_NAME);
	pSessionProperties = (EVENT_TRACE_PROPERTIES*)malloc(BufferSize);

	// Set the session properties. You only append the log file name
	// to the properties structure; the StartTrace function appends
	// the session name for you.

	ZeroMemory(pSessionProperties, BufferSize);
	pSessionProperties->Wnode.BufferSize = BufferSize;
	pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
	pSessionProperties->Wnode.ClientContext = 1; //QPC clock resolution
	pSessionProperties->Wnode.Guid = SystemTraceControlGuid;
	pSessionProperties->EnableFlags = EVENT_TRACE_FLAG_NETWORK_TCPIP;
	pSessionProperties->LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR;
	pSessionProperties->MaximumFileSize = 5;  // 5 MB
	pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
	pSessionProperties->LogFileNameOffset = sizeof(EVENT_TRACE_PROPERTIES) + sizeof(KERNEL_LOGGER_NAME);
	strcpy(((char*)pSessionProperties + pSessionProperties->LogFileNameOffset), LOGFILE_PATH);

	// Create the trace session.

	status = StartTrace((PTRACEHANDLE)&SessionHandle, KERNEL_LOGGER_NAME, pSessionProperties);

	if (ERROR_SUCCESS != status)
	{
			ErrorExit("EnableTrace");
	}

	wprintf(L"Press any key to end trace session ");
	getchar();
	return 0;
}

<|endoftext|>


<commit_before>//
// Created by dc on 9/26/17.
//
#include <suil/app.hpp>

namespace suil {

    static int   __notifyfd[2];
    static void __sighandler(int sig) {
        sdebug("signal %d received", sig);
        if (write(__notifyfd[1], &sig, sizeof(sig)) < 0) {
            /* writing signal failed */
            serror("[%d] notifying signal %d failed: %s",
                   __notifyfd[0], sig, errno_s);
            exit(errno);
        }
    }

    bool application::check(const char *name) {
        zcstring tmp(name);
        return tasks.find(name) != tasks.end();
    }

    int application::start() {
        debug("starting application with %d tasks", tasks.size());
        if (started) {
            throw suil_error::create("application aleady started");
        }

        if (pipe(__notifyfd)) {
            error("opening notification pipe failed: %s", errno_s);
            return EXIT_FAILURE;
        }

        /* register signal handlers */
        signal(SIGHUP,  __sighandler);
        signal(SIGQUIT, __sighandler);
        signal(SIGTERM, __sighandler);
        signal(SIGABRT, __sighandler);
        signal(SIGPIPE, SIG_IGN);

        started = 0;
        stopped = false;

        for (auto& it: tasks) {
            app_task& tmp = *it.second;
            // launch the tasks in a coroutine
            if (!tmp.running) {
                trace("launching coroutine for task-%s", tmp.name.cstr);
                started++;
                go(runtask(*this, it.second));
            }
            else {
                // running tasks shouldn't be started
                trace("task-%s already started", tmp.name.cstr);
            }
        }

        int code = EXIT_FAILURE;
        if (started) {
            /* wait for tasks to exit */
            debug("%u application tasks started", started);
            wait_notify(*this);
        }

        debug("application exited, {code=%d}", code);
        return code;
    }

    void application::wait_notify(application& app) {
        ldebug(&app, "wait exit notification coroutine started");
        int ev = fdwait(__notifyfd[0], FDW_IN, -1);
        if (ev == FDW_IN) {
            ltrace(&app, "read notify_fd[0] %d", ev);
            /* signal ready to read */
            int sig{0};
            if (read(__notifyfd[0], &sig, sizeof(sig)) > 0) {
                /* received signal, notify main loop */
                ltrace(&app, "signal %d received, stopping application", sig);
                app.stop(sig);
                return;
            }
        }
        ltrace(&app, "waiting for notice signal signal failed: %s", errno_s);
    }

    void application::stop(int code) {
        trace("stopping application, code=%d", code);
        stopped = true;

        uint32_t requested{0};
        for (auto& it : tasks) {
            app_task& tmp = *(it.second);
            if (!tmp.running) {
                trace("task-%s is not running", tmp.name.cstr);
            }
            else {
                trace("stopping task-%s", tmp.name.cstr);
                tmp.stop(code);
                requested++;
            }
        }

        if (requested > 0) {
            debug("{%ld} waiting for stopped %u tasks",
                  mnow(), requested);
            bool status;
            status = stopsync[timeout](requested) |
            [&](bool, app_task *task) {
                debug("task-%s exited {exitcode:%d}",
                      task->name.cstr, task->exitcode);
            };

            debug("{%ld} %u tasks exited", mnow(), requested);
            if (!status) {
                throw suil_error::create(
                        "stopping tasks timed out");
            }
        }

        close(__notifyfd[0]);
        close(__notifyfd[1]);
    }

    void application::runtask(application &app, app_task *task) {
        ltrace(&app, "starting task-%s", task->name.cstr);
        app.running_tasks++;

        try {
            task->running = true;
            task->start();
        } catch (...) {
            lerror(&app, "unhandled error in task-%s", task->name.cstr);
        }

        task->running = false;
        app.running_tasks--;

        if (app.stopped) {
            // notify stop
            ltrace(&app, "sending stop signal for task-%s", task->name.cstr);
            app.stopsync << task;
        }

        if (app.running_tasks == 0) {
            // all tasks exited, close app
            close(__notifyfd[0]);
            close(__notifyfd[1]);
        }
    }

    application::~application() {
        if (!stopped) {
            trace("stopping application in destructor, {running:%d}", running_tasks);
            stop(0);
        }

        auto it = tasks.begin();
        while (it != tasks.end()) {
            // delete task
            try {
                trace("deleting task-%s",
                      it->second->name.cstr);
                delete it->second;
                tasks.erase(it++);
            }
            catch (suil_error& ex) {
                warn("delete task unhandled suil_error: %s",
                     ex.what());
            }
            catch (...) {
                error("delete task unknown error");
            }
        }
    }
}
<commit_msg>- Adding support for application and tasks. - Also fixed the Suil.cmake script<commit_after>//
// Created by dc on 9/26/17.
//
#include <sys/wait.h>
#include <suil/app.hpp>

namespace suil {

    static int   __notifyfd[2];
    static void __sighandler(int sig) {
        sdebug("signal %d received", sig);
        if (write(__notifyfd[1], &sig, sizeof(sig)) < 0) {
            /* writing signal failed */
            serror("[%d] notifying signal %d failed: %s",
                   __notifyfd[0], sig, errno_s);
            exit(errno);
        }
    }

    bool application::check(const char *name) {
        zcstring tmp(name);
        return tasks.find(name) != tasks.end();
    }

    int application::start() {
        debug("starting application with %d tasks", tasks.size());
        if (started) {
            throw suil_error::create("application aleady started");
        }

        if (pipe(__notifyfd)) {
            error("opening notification pipe failed: %s", errno_s);
            return EXIT_FAILURE;
        }

        /* register signal handlers */
        signal(SIGHUP,  __sighandler);
        signal(SIGQUIT, __sighandler);
        signal(SIGTERM, __sighandler);
        signal(SIGABRT, __sighandler);
        signal(SIGPIPE, SIG_IGN);

        started = 0;
        stopped = false;

        for (auto& it: tasks) {
            app_task& tmp = *it.second;
            // launch the tasks in a coroutine
            if (!tmp.running) {
                trace("launching coroutine for task-%s", tmp.name.cstr);
                started++;
                go(runtask(*this, it.second));
            }
            else {
                // running tasks shouldn't be started
                trace("task-%s already started", tmp.name.cstr);
            }
        }

        int code = EXIT_FAILURE;
        if (started) {
            /* wait for tasks to exit */
            debug("%u application tasks started", started);
            wait_notify(*this);
        }

        debug("application exited, {code=%d}", code);
        return code;
    }

    void application::wait_notify(application& app) {
        ldebug(&app, "wait exit notification coroutine started");
        int ev = fdwait(__notifyfd[0], FDW_IN, -1);
        if (ev == FDW_IN) {
            ltrace(&app, "read notify_fd[0] %d", ev);
            /* signal ready to read */
            int sig{0};
            if (read(__notifyfd[0], &sig, sizeof(sig)) > 0) {
                /* received signal, notify main loop */
                ltrace(&app, "signal %d received, stopping application", sig);
                app.stop(sig);
                return;
            }
        }
        ltrace(&app, "waiting for notice signal signal failed: %s", errno_s);
    }

    void application::stop(int code) {
        trace("stopping application, code=%d", code);
        stopped = true;

        uint32_t requested{0};
        for (auto& it : tasks) {
            app_task& tmp = *(it.second);
            if (!tmp.running) {
                trace("task-%s is not running", tmp.name.cstr);
            }
            else {
                trace("stopping task-%s", tmp.name.cstr);
                tmp.stop(code);
                requested++;
            }
        }

        if (requested > 0) {
            debug("{%ld} waiting for stopped %u tasks",
                  mnow(), requested);
            bool status;
            status = stopsync[timeout](requested) |
            [&](bool, app_task *task) {
                debug("task-%s exited {exitcode:%d}",
                      task->name.cstr, task->exitcode);
            };

            debug("{%ld} %u tasks exited", mnow(), requested);
            if (!status) {
                throw suil_error::create(
                        "stopping tasks timed out");
            }
        }

        close(__notifyfd[0]);
        close(__notifyfd[1]);
    }

    void application::runtask(application &app, app_task *task) {
        ltrace(&app, "starting task-%s", task->name.cstr);
        app.running_tasks++;

        try {
            task->running = true;
            task->start();
        } catch (...) {
            lerror(&app, "unhandled error in task-%s", task->name.cstr);
        }

        task->running = false;
        app.running_tasks--;

        if (app.stopped) {
            // notify stop
            ltrace(&app, "sending stop signal for task-%s", task->name.cstr);
            app.stopsync << task;
        }

        if (app.running_tasks == 0) {
            // all tasks exited, close app
            close(__notifyfd[0]);
            close(__notifyfd[1]);
        }
    }

    application::~application() {
        if (!stopped) {
            trace("stopping application in destructor, {running:%d}", running_tasks);
            stop(0);
        }

        auto it = tasks.begin();
        while (it != tasks.end()) {
            // delete task
            try {
                trace("deleting task-%s",
                      it->second->name.cstr);
                delete it->second;
                tasks.erase(it++);
            }
            catch (suil_error& ex) {
                warn("delete task unhandled suil_error: %s",
                     ex.what());
            }
            catch (...) {
                error("delete task unknown error");
            }
        }
    }
}
<|endoftext|>


<commit_before>// Example to illustrate the 2-d peak finder (class TSpectrum2).
// This script generates a random number of 2-d gaussian peaks
// The position of the peaks is found via TSpectrum2
// To execute this example, do
//  root > .x peaks2.C  (generate up to 50 peaks by default)
//  root > .x peaks2.C(10) (generate up to 10 peaks)
//  root > .x peaks2.C+(200) (generate up to 200 peaks via ACLIC)
//
// The script will iterate generating a new histogram having
// between 5 and the maximun number of peaks specified.
// Double Click on the bottom right corner of the pad to go to a new spectrum
// To Quit, select the "quit" item in the canvas "File" menu
//
// Author: Rene Brun

#include "TSpectrum2.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TH2.h"
#include "TF2.h"

TSpectrum2 *s;
TH2F *h2 = 0;
Int_t npeaks = 30;
Double_t fpeaks2(Double_t *x, Double_t *par) {
   Double_t result = 0.1;
   for (Int_t p=0;p<npeaks;p++) {
      Double_t norm   = par[5*p+0];
      Double_t mean1  = par[5*p+1];
      Double_t sigma1 = par[5*p+2];
      Double_t mean2  = par[5*p+3];
      Double_t sigma2 = par[5*p+4];
      result += norm*TMath::Gaus(x[0],mean1,sigma1)*TMath::Gaus(x[1],mean2,sigma2);
   }
   return result;
}
void findPeak2() {
   printf("Generating histogram with %d peaks\n",npeaks);
   Int_t nbinsx = 200;
   Int_t nbinsy = 200;
   Double_t xmin   = 0;
   Double_t xmax   = (Double_t)nbinsx;
   Double_t ymin   = 0;
   Double_t ymax   = (Double_t)nbinsy;
   Double_t dx = (xmax-xmin)/nbinsx;
   Double_t dy = (ymax-ymin)/nbinsy;
   delete h2;
   h2 = new TH2F("h2","test",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
   h2->SetStats(0);
   //generate n peaks at random
   Double_t par[3000];
   Int_t p;
   for (p=0;p<npeaks;p++) {
      par[5*p+0] = gRandom->Uniform(0.2,1);
      par[5*p+1] = gRandom->Uniform(xmin,xmax);
      par[5*p+2] = gRandom->Uniform(dx,5*dx);
      par[5*p+3] = gRandom->Uniform(ymin,ymax);
      par[5*p+4] = gRandom->Uniform(dy,5*dy);
   }
   TF2 *f2 = new TF2("f2",fpeaks2,xmin,xmax,ymin,ymax,5*npeaks);
   f2->SetNpx(100);
   f2->SetNpy(100);
   f2->SetParameters(par);
   TCanvas *c1 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c1");
   if (!c1) c1 = new TCanvas("c1","c1",10,10,1000,700);
   h2->FillRandom("f2",500000);
   //now the real stuff
   printf("starting Search\n");
   Int_t nfound = s->Search(h2,2,"col");
   printf("Finished Search\n");

   //searching good and ghost peaks (approximation)
   Int_t pf,ngood = 0;
   Float_t *xpeaks = s->GetPositionX();
   Float_t *ypeaks = s->GetPositionY();
   for (p=0;p<npeaks;p++) {
      for (Int_t pf=0;pf<nfound;pf++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) ngood++;
      }
   }
   if (ngood > nfound) ngood = nfound;
   //Search ghost peaks (approximation)
   Int_t nghost = 0;
   for (pf=0;pf<nfound;pf++) {
      Int_t nf=0;
      for (Int_t p=0;p<npeaks;p++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) nf++;
      }
      if (nf == 0) nghost++;
   }
   c1->Update();

   s->Print();
   printf("Gener=%d, Found=%d, Good=%d, Ghost=%d\n",npeaks,nfound,ngood,nghost);
   printf("\nDouble click in the bottom right corner of the pad to continue\n");
   c1->WaitPrimitive();
}
void peaks2(Int_t maxpeaks=50) {
   s = new TSpectrum2(2*maxpeaks);
   while (1) {
      npeaks = (Int_t)gRandom->Uniform(5,maxpeaks);
      findPeak2();
   }
}

<commit_msg>Remove two debug printf<commit_after>// Example to illustrate the 2-d peak finder (class TSpectrum2).
// This script generates a random number of 2-d gaussian peaks
// The position of the peaks is found via TSpectrum2
// To execute this example, do
//  root > .x peaks2.C  (generate up to 50 peaks by default)
//  root > .x peaks2.C(10) (generate up to 10 peaks)
//  root > .x peaks2.C+(200) (generate up to 200 peaks via ACLIC)
//
// The script will iterate generating a new histogram having
// between 5 and the maximun number of peaks specified.
// Double Click on the bottom right corner of the pad to go to a new spectrum
// To Quit, select the "quit" item in the canvas "File" menu
//
// Author: Rene Brun

#include "TSpectrum2.h"
#include "TCanvas.h"
#include "TRandom.h"
#include "TH2.h"
#include "TF2.h"

TSpectrum2 *s;
TH2F *h2 = 0;
Int_t npeaks = 30;
Double_t fpeaks2(Double_t *x, Double_t *par) {
   Double_t result = 0.1;
   for (Int_t p=0;p<npeaks;p++) {
      Double_t norm   = par[5*p+0];
      Double_t mean1  = par[5*p+1];
      Double_t sigma1 = par[5*p+2];
      Double_t mean2  = par[5*p+3];
      Double_t sigma2 = par[5*p+4];
      result += norm*TMath::Gaus(x[0],mean1,sigma1)*TMath::Gaus(x[1],mean2,sigma2);
   }
   return result;
}
void findPeak2() {
   printf("Generating histogram with %d peaks\n",npeaks);
   Int_t nbinsx = 200;
   Int_t nbinsy = 200;
   Double_t xmin   = 0;
   Double_t xmax   = (Double_t)nbinsx;
   Double_t ymin   = 0;
   Double_t ymax   = (Double_t)nbinsy;
   Double_t dx = (xmax-xmin)/nbinsx;
   Double_t dy = (ymax-ymin)/nbinsy;
   delete h2;
   h2 = new TH2F("h2","test",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
   h2->SetStats(0);
   //generate n peaks at random
   Double_t par[3000];
   Int_t p;
   for (p=0;p<npeaks;p++) {
      par[5*p+0] = gRandom->Uniform(0.2,1);
      par[5*p+1] = gRandom->Uniform(xmin,xmax);
      par[5*p+2] = gRandom->Uniform(dx,5*dx);
      par[5*p+3] = gRandom->Uniform(ymin,ymax);
      par[5*p+4] = gRandom->Uniform(dy,5*dy);
   }
   TF2 *f2 = new TF2("f2",fpeaks2,xmin,xmax,ymin,ymax,5*npeaks);
   f2->SetNpx(100);
   f2->SetNpy(100);
   f2->SetParameters(par);
   TCanvas *c1 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject("c1");
   if (!c1) c1 = new TCanvas("c1","c1",10,10,1000,700);
   h2->FillRandom("f2",500000);

   //now the real stuff: Finding the peaks
   Int_t nfound = s->Search(h2,2,"col");

   //searching good and ghost peaks (approximation)
   Int_t pf,ngood = 0;
   Float_t *xpeaks = s->GetPositionX();
   Float_t *ypeaks = s->GetPositionY();
   for (p=0;p<npeaks;p++) {
      for (Int_t pf=0;pf<nfound;pf++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) ngood++;
      }
   }
   if (ngood > nfound) ngood = nfound;
   //Search ghost peaks (approximation)
   Int_t nghost = 0;
   for (pf=0;pf<nfound;pf++) {
      Int_t nf=0;
      for (Int_t p=0;p<npeaks;p++) {
         Double_t diffx = TMath::Abs(xpeaks[pf] - par[5*p+1]);
         Double_t diffy = TMath::Abs(ypeaks[pf] - par[5*p+3]);
         if (diffx < 2*dx && diffy < 2*dy) nf++;
      }
      if (nf == 0) nghost++;
   }
   c1->Update();

   s->Print();
   printf("Gener=%d, Found=%d, Good=%d, Ghost=%d\n",npeaks,nfound,ngood,nghost);
   printf("\nDouble click in the bottom right corner of the pad to continue\n");
   c1->WaitPrimitive();
}
void peaks2(Int_t maxpeaks=50) {
   s = new TSpectrum2(2*maxpeaks);
   while (1) {
      npeaks = (Int_t)gRandom->Uniform(5,maxpeaks);
      findPeak2();
   }
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <random>

#include <unsupported/Eigen/SparseExtra>

#ifdef _OPENMP
#include <omp.h>
#else
#include <tbb/tbb.h>
#endif

#include "bpmf.h"

using namespace std;
using namespace Eigen;

const int num_feat = 64;

const double alpha = 2;
const int nsims = 20;
const int burnin = 10;

double mean_rating = .0;

typedef SparseMatrix<double> SparseMatrixD;
SparseMatrixD M, Mt, P;

typedef Matrix<double, num_feat, 1> VectorNd;
typedef Matrix<double, num_feat, num_feat> MatrixNNd;
typedef Matrix<double, num_feat, Dynamic> MatrixNXd;

VectorNd mu_u;
VectorNd mu_m;
MatrixNNd Lambda_u;
MatrixNNd Lambda_m;
MatrixNXd sample_u;
MatrixNXd sample_m;

// parameters of Inv-Whishart distribution (see paper for details)
MatrixNNd WI_u;
const int b0_u = 2;
const int df_u = num_feat;
VectorNd mu0_u;

MatrixNNd WI_m;
const int b0_m = 2;
const int df_m = num_feat;
VectorNd mu0_m;

void init() {
    mean_rating = M.sum() / M.nonZeros();
    Lambda_u.setIdentity();
    Lambda_m.setIdentity();

    sample_u = MatrixNXd(num_feat,M.rows());
    sample_m = MatrixNXd(num_feat,M.cols());
    sample_u.setZero();
    sample_m.setZero();

    // parameters of Inv-Whishart distribution (see paper for details)
    WI_u.setIdentity();
    mu0_u.setZero();

    WI_m.setIdentity();
    mu0_m.setZero();
}

inline double sqr(double x) { return x*x; }

std::pair<double,double> eval_probe_vec(int n, VectorXd & predictions, const MatrixNXd &sample_m, const MatrixNXd &sample_u, double mean_rating)
{
    double se = 0.0, se_avg = 0.0;
    unsigned idx = 0;
    for (int k=0; k<P.outerSize(); ++k) {
        for (SparseMatrix<double>::InnerIterator it(P,k); it; ++it) {
            const double pred = sample_m.col(it.col()).dot(sample_u.col(it.row())) + mean_rating;
            //se += (it.value() < log10(200)) == (pred < log10(200));
            se += sqr(it.value() - pred);

            const double pred_avg = (n == 0) ? pred : (predictions[idx] + (pred - predictions[idx]) / n);
            //se_avg += (it.value() < log10(200)) == (pred_avg < log10(200));
            se_avg += sqr(it.value() - pred_avg);
            predictions[idx++] = pred_avg;
        }
    }

    const unsigned N = P.nonZeros();
    const double rmse = sqrt( se / N );
    const double rmse_avg = sqrt( se_avg / N );
    return std::make_pair(rmse, rmse_avg);
}

void sample(MatrixNXd &s, int mm, const SparseMatrixD &mat, double mean_rating,
    const MatrixNXd &samples, double alpha, const VectorNd &mu, const MatrixNNd &LambdaU, const MatrixNNd &Lambda)
{

		int count = 0;
		for (SparseMatrixD::InnerIterator it(mat,mm); it; ++it, ++count)
			if( count > BREAKPOINT )
				break;

		VectorNd rr; rr.setZero();
		Eigen::LLT<MatrixNNd> chol;

		if( count < BREAKPOINT ) {
			const_cast<MatrixNNd&>( chol.matrixLLT() ) = LambdaU.transpose();
			for (SparseMatrixD::InnerIterator it(mat,mm); it; ++it) {
					auto col = samples.col(it.row());
					chol.rankUpdate(col, alpha);
					rr.noalias() += col * ((it.value() - mean_rating) * alpha);
			}
		} else {
			MatrixNNd MM; MM.setZero();
			for (SparseMatrixD::InnerIterator it(mat,mm); it; ++it) {
					auto col = samples.col(it.row());
					MM.noalias() += col * col.transpose();
					rr.noalias() += col * ((it.value() - mean_rating) * alpha);
			}

			chol = (Lambda + alpha * MM).llt();
		}

		if(chol.info() != Eigen::Success)
			throw std::runtime_error("Cholesky Decomposition failed!");

    VectorNd tmp = rr + Lambda * mu;
    chol.matrixL().solveInPlace(tmp);
    tmp += nrandn(num_feat);
    chol.matrixU().solveInPlace(tmp);
    s.col(mm) = tmp;

#ifdef TEST_SAMPLE
      cout << "movie " << mm << ":" << result.cols() << " x" << result.rows() << endl;
      cout << "mean rating " << mean_rating << endl;
      cout << "E = [" << E << "]" << endl;
      cout << "rr = [" << rr << "]" << endl;
      cout << "MM = [" << MM << "]" << endl;
      cout << "Lambda_u = [" << Lambda_u << "]" << endl;
      cout << "covar = [" << covar << "]" << endl;
      cout << "mu = [" << mu << "]" << endl;
      cout << "chol = [" << chol << "]" << endl;
      cout << "rand = [" << r <<"]" <<  endl;
      cout << "result = [" << result << "]" << endl;
#endif

}

#ifdef TEST_SAMPLE
void test() {
    MatrixNXd sample_u(M.rows());
    MatrixNXd sample_m(M.cols());

    mu_m.setZero();
    Lambda_m.setIdentity();
    sample_u.setConstant(2.0);
    Lambda_m *= 0.5;
    sample_m.col(0) = sample(0, M, mean_rating, sample_u, alpha, mu_m, Lambda_m);
}

#else

void run() {
		VectorXd predictions;
		predictions = VectorXd::Zero( P.nonZeros() );

		MatrixNNd Lambda_mf, Lambda_uf;

    auto start = tick();
    std::cout << "Sampling" << endl;
    for(int i=0; i<nsims; ++i) {

      // Sample from movie hyperparams
      tie(mu_m, Lambda_m) = CondNormalWishart(sample_m, mu0_m, b0_m, WI_m, df_m);
			Lambda_mf = Lambda_m.triangularView<Upper>().transpose() * Lambda_m;

      // Sample from user hyperparams
      tie(mu_u, Lambda_u) = CondNormalWishart(sample_u, mu0_u, b0_u, WI_u, df_u);
			Lambda_uf = Lambda_u.triangularView<Upper>().transpose() * Lambda_u;

      const int num_m = M.cols();
      const int num_u = M.rows();
#ifdef _OPENMP
#pragma omp parallel for
      for(int mm=0; mm<num_m; ++mm) {
        sample(sample_m, mm, M, mean_rating, sample_u, alpha, mu_m, Lambda_m, Lambda_mf);
      }
#pragma omp parallel for
      for(int uu=0; uu<num_u; ++uu) {
        sample(sample_u, uu, Mt, mean_rating, sample_m, alpha, mu_u, Lambda_u, Lambda_uf);
      }
#else
      tbb::parallel_for(0, num_m, [](int mm) {
        sample(sample_m, mm, M, mean_rating, sample_u, alpha, mu_m, Lambda_m);
      });

      tbb::parallel_for(0, num_u, [](int uu) {
         sample(sample_u, uu, Mt, mean_rating, sample_m, alpha, mu_u, Lambda_u);
       });
#endif

      auto eval = eval_probe_vec( (i < burnin) ? 0 : (i - burnin), predictions, sample_m, sample_u, mean_rating);
//      auto eval = std::make_pair(0.0, 0.0);
      double norm_u = sample_u.norm();
      double norm_m = sample_m.norm();
      auto end = tick();
      auto elapsed = end - start;
      double samples_per_sec = (i + 1) * (M.rows() + M.cols()) / elapsed;

      printf("Iteration %d:\t RMSE: %3.2f\tavg RMSE: %3.2f\tFU(%6.2f)\tFM(%6.2f)\tSamples/sec: %6.2f\n",
              i, eval.first, eval.second, norm_u, norm_m, samples_per_sec);
    }

  auto end = tick();
  auto elapsed = end - start;
  printf("Total time: %6.2f\n", elapsed);
}

#endif

int main(int argc, char *argv[])
{
    if(argc < 3) {
       cerr << "Usage: " << argv[0] << " <train_matrix.mtx> <test_matrix.mtx>" << endl;
       abort();
    }

    cerr << "num_feat: " << num_feat << endl;
    cerr << "nsims: " << nsims << endl;
    cerr << "burnin: " << burnin << endl;

    Eigen::initParallel();

    cerr << "Loading training matrix (" << argv[1] << ")" << endl;
    loadMarket(M, argv[1]);
    Mt = M.transpose();

    cerr << "Loading test matrix (" << argv[2] << ")" << endl;
    loadMarket(P, argv[2]);

    assert(M.nonZeros() > P.nonZeros());

    init();
#ifdef TEST_SAMPLE
    test();
#else
    run();
#endif

    return 0;
}
<commit_msg>PrecomputedLLT class<commit_after>
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <random>

#include <unsupported/Eigen/SparseExtra>

#ifdef _OPENMP
#include <omp.h>
#else
#include <tbb/tbb.h>
#endif

#include "bpmf.h"

using namespace std;
using namespace Eigen;

const int num_feat = 64;

const double alpha = 2;
const int nsims = 20;
const int burnin = 10;

double mean_rating = .0;

typedef SparseMatrix<double> SparseMatrixD;
SparseMatrixD M, Mt, P;

typedef Matrix<double, num_feat, 1> VectorNd;
typedef Matrix<double, num_feat, num_feat> MatrixNNd;
typedef Matrix<double, num_feat, Dynamic> MatrixNXd;

VectorNd mu_u;
VectorNd mu_m;
MatrixNNd Lambda_u;
MatrixNNd Lambda_m;
MatrixNXd sample_u;
MatrixNXd sample_m;

// parameters of Inv-Whishart distribution (see paper for details)
MatrixNNd WI_u;
const int b0_u = 2;
const int df_u = num_feat;
VectorNd mu0_u;

MatrixNNd WI_m;
const int b0_m = 2;
const int df_m = num_feat;
VectorNd mu0_m;

void init() {
    mean_rating = M.sum() / M.nonZeros();
    Lambda_u.setIdentity();
    Lambda_m.setIdentity();

    sample_u = MatrixNXd(num_feat,M.rows());
    sample_m = MatrixNXd(num_feat,M.cols());
    sample_u.setZero();
    sample_m.setZero();

    // parameters of Inv-Whishart distribution (see paper for details)
    WI_u.setIdentity();
    mu0_u.setZero();

    WI_m.setIdentity();
    mu0_m.setZero();
}

inline double sqr(double x) { return x*x; }

std::pair<double,double> eval_probe_vec(int n, VectorXd & predictions, const MatrixNXd &sample_m, const MatrixNXd &sample_u, double mean_rating)
{
    double se = 0.0, se_avg = 0.0;
    unsigned idx = 0;
    for (int k=0; k<P.outerSize(); ++k) {
        for (SparseMatrix<double>::InnerIterator it(P,k); it; ++it) {
            const double pred = sample_m.col(it.col()).dot(sample_u.col(it.row())) + mean_rating;
            //se += (it.value() < log10(200)) == (pred < log10(200));
            se += sqr(it.value() - pred);

            const double pred_avg = (n == 0) ? pred : (predictions[idx] + (pred - predictions[idx]) / n);
            //se_avg += (it.value() < log10(200)) == (pred_avg < log10(200));
            se_avg += sqr(it.value() - pred_avg);
            predictions[idx++] = pred_avg;
        }
    }

    const unsigned N = P.nonZeros();
    const double rmse = sqrt( se / N );
    const double rmse_avg = sqrt( se_avg / N );
    return std::make_pair(rmse, rmse_avg);
}

class PrecomputedLLT : public Eigen::LLT<MatrixNNd>
{
  public:
    void operator=(const MatrixNNd &m) { m_matrix = m; m_isInitialized = true; m_info = Success; }
    void operator=(const LLT<MatrixNNd> &m) { m_matrix = m.matrixLLT(); m_isInitialized = true; m_info = m.info(); }
};

void sample(MatrixNXd &s, int mm, const SparseMatrixD &mat, double mean_rating,
    const MatrixNXd &samples, double alpha, const VectorNd &mu, const MatrixNNd &LambdaU, const MatrixNNd &Lambda)
{

		int count = 0;
		for (SparseMatrixD::InnerIterator it(mat,mm); it; ++it, ++count)
			if( count > BREAKPOINT )
				break;

		VectorNd rr; rr.setZero();
		PrecomputedLLT chol;

		if( count < BREAKPOINT ) {
			chol = LambdaU.transpose();
			for (SparseMatrixD::InnerIterator it(mat,mm); it; ++it) {
					auto col = samples.col(it.row());
					chol.rankUpdate(col, alpha);
					rr.noalias() += col * ((it.value() - mean_rating) * alpha);
			}
		} else {
			MatrixNNd MM; MM.setZero();
			for (SparseMatrixD::InnerIterator it(mat,mm); it; ++it) {
					auto col = samples.col(it.row());
					MM.noalias() += col * col.transpose();
					rr.noalias() += col * ((it.value() - mean_rating) * alpha);
			}

			chol = (Lambda + alpha * MM).llt();
		}

		if(chol.info() != Eigen::Success)
			throw std::runtime_error("Cholesky Decomposition failed!");

    VectorNd tmp = rr + Lambda * mu;
    chol.matrixL().solveInPlace(tmp);
    tmp += nrandn(num_feat);
    chol.matrixU().solveInPlace(tmp);
    s.col(mm) = tmp;

#ifdef TEST_SAMPLE
      cout << "movie " << mm << ":" << result.cols() << " x" << result.rows() << endl;
      cout << "mean rating " << mean_rating << endl;
      cout << "E = [" << E << "]" << endl;
      cout << "rr = [" << rr << "]" << endl;
      cout << "MM = [" << MM << "]" << endl;
      cout << "Lambda_u = [" << Lambda_u << "]" << endl;
      cout << "covar = [" << covar << "]" << endl;
      cout << "mu = [" << mu << "]" << endl;
      cout << "chol = [" << chol << "]" << endl;
      cout << "rand = [" << r <<"]" <<  endl;
      cout << "result = [" << result << "]" << endl;
#endif

}

#ifdef TEST_SAMPLE
void test() {
    MatrixNXd sample_u(M.rows());
    MatrixNXd sample_m(M.cols());

    mu_m.setZero();
    Lambda_m.setIdentity();
    sample_u.setConstant(2.0);
    Lambda_m *= 0.5;
    sample_m.col(0) = sample(0, M, mean_rating, sample_u, alpha, mu_m, Lambda_m);
}

#else

void run() {
		VectorXd predictions;
		predictions = VectorXd::Zero( P.nonZeros() );

		MatrixNNd Lambda_mf, Lambda_uf;

    auto start = tick();
    std::cout << "Sampling" << endl;
    for(int i=0; i<nsims; ++i) {

      // Sample from movie hyperparams
      tie(mu_m, Lambda_m) = CondNormalWishart(sample_m, mu0_m, b0_m, WI_m, df_m);
			Lambda_mf = Lambda_m.triangularView<Upper>().transpose() * Lambda_m;

      // Sample from user hyperparams
      tie(mu_u, Lambda_u) = CondNormalWishart(sample_u, mu0_u, b0_u, WI_u, df_u);
			Lambda_uf = Lambda_u.triangularView<Upper>().transpose() * Lambda_u;

      const int num_m = M.cols();
      const int num_u = M.rows();
#ifdef _OPENMP
#pragma omp parallel for
      for(int mm=0; mm<num_m; ++mm) {
        sample(sample_m, mm, M, mean_rating, sample_u, alpha, mu_m, Lambda_m, Lambda_mf);
      }
#pragma omp parallel for
      for(int uu=0; uu<num_u; ++uu) {
        sample(sample_u, uu, Mt, mean_rating, sample_m, alpha, mu_u, Lambda_u, Lambda_uf);
      }
#else
      tbb::parallel_for(0, num_m, [](int mm) {
        sample(sample_m, mm, M, mean_rating, sample_u, alpha, mu_m, Lambda_m);
      });

      tbb::parallel_for(0, num_u, [](int uu) {
         sample(sample_u, uu, Mt, mean_rating, sample_m, alpha, mu_u, Lambda_u);
       });
#endif

      auto eval = eval_probe_vec( (i < burnin) ? 0 : (i - burnin), predictions, sample_m, sample_u, mean_rating);
//      auto eval = std::make_pair(0.0, 0.0);
      double norm_u = sample_u.norm();
      double norm_m = sample_m.norm();
      auto end = tick();
      auto elapsed = end - start;
      double samples_per_sec = (i + 1) * (M.rows() + M.cols()) / elapsed;

      printf("Iteration %d:\t RMSE: %3.2f\tavg RMSE: %3.2f\tFU(%6.2f)\tFM(%6.2f)\tSamples/sec: %6.2f\n",
              i, eval.first, eval.second, norm_u, norm_m, samples_per_sec);
    }

  auto end = tick();
  auto elapsed = end - start;
  printf("Total time: %6.2f\n", elapsed);
}

#endif

int main(int argc, char *argv[])
{
    if(argc < 3) {
       cerr << "Usage: " << argv[0] << " <train_matrix.mtx> <test_matrix.mtx>" << endl;
       abort();
    }

    cerr << "num_feat: " << num_feat << endl;
    cerr << "nsims: " << nsims << endl;
    cerr << "burnin: " << burnin << endl;

    Eigen::initParallel();

    cerr << "Loading training matrix (" << argv[1] << ")" << endl;
    loadMarket(M, argv[1]);
    Mt = M.transpose();

    cerr << "Loading test matrix (" << argv[2] << ")" << endl;
    loadMarket(P, argv[2]);

    assert(M.nonZeros() > P.nonZeros());

    init();
#ifdef TEST_SAMPLE
    test();
#else
    run();
#endif

    return 0;
}
<|endoftext|>


<commit_before>#include "Grid.h"

#include <cassert>
#include "Tile.h"

#ifdef DEBUG
#include <iostream>
#endif

namespace
{
#ifdef DEBUG
    void assertGridIsRectangular(std::list<std::list<bool>*>& tiles)
    {
        //sanity check
        assert(!tiles.empty());

        //check the grid is rectangular and not jagged
        //i.e. all sublists are the same size
        //note that the number of sublists does not have to be equal to the number of columns
        for(std::list<bool>* thisSubList : tiles)
        {
            for(std::list<bool>* otherSubList : tiles)
            {
                assert(!otherSubList->empty());
                std::cerr << "thisSubList->size():  " << thisSubList->size() << ", otherSubList->size():  " << otherSubList->size() << std::endl;
                assert(thisSubList->size() == otherSubList->size());
            }
        }
    }
#endif
}

int Grid::getWidth()
{
    return tiles.front()->size();
}

int Grid::getHeight()
{
    return tiles.size();
}

void Grid::expandGrid()
{
    //check the grid is the right shape before and after we modify it
#ifdef DEBUG
//    assertGridIsRectangular(tiles);
#endif
    const int newWidth = getWidth() + 2;

    //add 1 tile to the beginning of each sublist (prepending a column)
    //add 1 tile to the end of each sublist (appending a column)
    for(std::list<bool>* thisSubList : tiles)
    {
        thisSubList->push_front(TILE_DEAD);
        thisSubList->push_back(TILE_DEAD);
    }

    //add 1 row to the beginning of the tiles list (prepending a row)
    //add 1 row to the end of the tiles list (appending a column)
    std::list<bool> *firstList = new std::list<bool>(newWidth, TILE_DEAD),
        *lastList = new std::list<bool>(newWidth, TILE_DEAD);
    tiles.push_front(firstList);
    tiles.push_back(lastList);

#ifdef DEBUG
    //check the size is correct
//    assertGridIsRectangular(tiles);
#endif
}

bool Grid::touchingEdges()
{
    //TODO: IMPLEMENT
    return true;
}

Grid::Grid(const Grid& other)
{
    //TODO: IMPLEMENT
}

Grid::Grid(const int width, const int height)
{
    for(int i = 0; i < height; i++)
    {
        //don't have to loop to add items to the list
        //this list CTOR will insert <width> number of bools all at once
        std::list<bool>* subList = new std::list<bool>(width, TILE_DEAD);
        //insert the sublist
        tiles.push_back(subList);
    }
}

Grid::~Grid()
{
    for(std::list<bool>* thisSubList : tiles)
    {
        delete thisSubList;
    }
}
<commit_msg>removed unnecessary print statement, re-entered assert calls<commit_after>#include "Grid.h"

#include <cassert>
#include "Tile.h"

#ifdef DEBUG
#include <iostream>
#endif

namespace
{
#ifdef DEBUG
    void assertGridIsRectangular(std::list<std::list<bool>*>& tiles)
    {
        //sanity check
        assert(!tiles.empty());

        //check the grid is rectangular and not jagged
        //i.e. all sublists are the same size
        //note that the number of sublists does not have to be equal to the number of columns
        for(std::list<bool>* thisSubList : tiles)
        {
            for(std::list<bool>* otherSubList : tiles)
            {
                assert(!otherSubList->empty());
                assert(thisSubList->size() == otherSubList->size());
            }
        }
    }
#endif
}

int Grid::getWidth()
{
    return tiles.front()->size();
}

int Grid::getHeight()
{
    return tiles.size();
}

void Grid::expandGrid()
{
    //check the grid is the right shape before and after we modify it
#ifdef DEBUG
    assertGridIsRectangular(tiles);
#endif
    const int newWidth = getWidth() + 2;

    //add 1 tile to the beginning of each sublist (prepending a column)
    //add 1 tile to the end of each sublist (appending a column)
    for(std::list<bool>* thisSubList : tiles)
    {
        thisSubList->push_front(TILE_DEAD);
        thisSubList->push_back(TILE_DEAD);
    }

    //add 1 row to the beginning of the tiles list (prepending a row)
    //add 1 row to the end of the tiles list (appending a column)
    std::list<bool> *firstList = new std::list<bool>(newWidth, TILE_DEAD),
        *lastList = new std::list<bool>(newWidth, TILE_DEAD);
    tiles.push_front(firstList);
    tiles.push_back(lastList);

#ifdef DEBUG
    //check the size is correct
    assertGridIsRectangular(tiles);
#endif
}

bool Grid::touchingEdges()
{
    //TODO: IMPLEMENT
    return true;
}

Grid::Grid(const Grid& other)
{
    //TODO: IMPLEMENT
}

Grid::Grid(const int width, const int height)
{
    for(int i = 0; i < height; i++)
    {
        //don't have to loop to add items to the list
        //this list CTOR will insert <width> number of bools all at once
        std::list<bool>* subList = new std::list<bool>(width, TILE_DEAD);
        //insert the sublist
        tiles.push_back(subList);
    }
}

Grid::~Grid()
{
    for(std::list<bool>* thisSubList : tiles)
    {
        delete thisSubList;
    }
}
<|endoftext|>