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

  This file is part of the elastix software.

  Copyright (c) University Medical Center Utrecht. All rights reserved.
  See src/CopyrightElastix.txt or http://elastix.isi.uu.nl/legal.php 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.

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

#ifndef __elxAdvancedMattesMutualInformationMetric_HXX__
#define __elxAdvancedMattesMutualInformationMetric_HXX__

#include "elxAdvancedMattesMutualInformationMetric.h"
#include "itkHardLimiterFunction.h"
#include "itkExponentialLimiterFunction.h"
#include <string>
#include "vnl/vnl_math.h"

namespace elastix
{
using namespace itk;

  /**
   * ****************** Constructor ***********************
   */

  template <class TElastix>
    AdvancedMattesMutualInformationMetric<TElastix>
    ::AdvancedMattesMutualInformationMetric()
  {
    this->m_Param_c = 1.0;
    this->m_Param_gamma = 0.101;
    this->SetUseDerivative( true );

  } // end Constructor()

  /**
   * ******************* Initialize ***********************
   */

  template <class TElastix>
    void AdvancedMattesMutualInformationMetric<TElastix>
    ::Initialize( void ) throw (ExceptionObject)
  {
    TimerPointer timer = TimerType::New();
    timer->StartTimer();
    this->Superclass1::Initialize();
    timer->StopTimer();
    elxout << "Initialization of AdvancedMattesMutualInformation metric took: "
      << static_cast<long>( timer->GetElapsedClockSec() * 1000 ) << " ms." << std::endl;

  } // end Initialize()

  /**
   * ***************** BeforeEachResolution ***********************
   */

  template <class TElastix>
    void AdvancedMattesMutualInformationMetric<TElastix>
    ::BeforeEachResolution( void )
  {
    /** Get the current resolution level. */
    unsigned int level =
      ( this->m_Registration->GetAsITKBaseType() )->GetCurrentLevel();

    /** Get and set the number of histogram bins. */
    unsigned int numberOfHistogramBins = 32;
    this->GetConfiguration()->ReadParameter( numberOfHistogramBins,
      "NumberOfHistogramBins", this->GetComponentLabel(), level, 0 );
    this->SetNumberOfFixedHistogramBins( numberOfHistogramBins );
    this->SetNumberOfMovingHistogramBins( numberOfHistogramBins );

    unsigned int numberOfFixedHistogramBins = numberOfHistogramBins;
    unsigned int numberOfMovingHistogramBins = numberOfHistogramBins;
    this->GetConfiguration()->ReadParameter( numberOfFixedHistogramBins,
      "NumberOfFixedHistogramBins", this->GetComponentLabel(), level, 0 );
    this->GetConfiguration()->ReadParameter( numberOfMovingHistogramBins,
      "NumberOfMovingHistogramBins", this->GetComponentLabel(), level, 0 );
    this->SetNumberOfFixedHistogramBins( numberOfFixedHistogramBins );
    this->SetNumberOfMovingHistogramBins( numberOfMovingHistogramBins );

    /** Set limiters. */
    typedef HardLimiterFunction< RealType, FixedImageDimension > FixedLimiterType;
    typedef ExponentialLimiterFunction< RealType, MovingImageDimension > MovingLimiterType;
    this->SetFixedImageLimiter( FixedLimiterType::New() );
    this->SetMovingImageLimiter( MovingLimiterType::New() );

    /** Get and set the limit range ratios. */
    double fixedLimitRangeRatio = 0.01;
    double movingLimitRangeRatio = 0.01;
    this->GetConfiguration()->ReadParameter( fixedLimitRangeRatio,
      "FixedLimitRangeRatio", this->GetComponentLabel(), level, 0 );
    this->GetConfiguration()->ReadParameter( movingLimitRangeRatio,
      "MovingLimitRangeRatio", this->GetComponentLabel(), level, 0 );
    this->SetFixedLimitRangeRatio( fixedLimitRangeRatio );
    this->SetMovingLimitRangeRatio( movingLimitRangeRatio );

    /** Set B-spline Parzen kernel orders. */
    unsigned int fixedKernelBSplineOrder = 0;
    unsigned int movingKernelBSplineOrder = 3;
    this->GetConfiguration()->ReadParameter( fixedKernelBSplineOrder,
      "FixedKernelBSplineOrder", this->GetComponentLabel(), level, 0 );
    this->GetConfiguration()->ReadParameter( movingKernelBSplineOrder,
      "MovingKernelBSplineOrder", this->GetComponentLabel(), level, 0 );
    this->SetFixedKernelBSplineOrder( fixedKernelBSplineOrder );
    this->SetMovingKernelBSplineOrder( movingKernelBSplineOrder );

    /** Set whether a low memory consumption should be used. */
    bool useFastAndLowMemoryVersion = true;
    this->GetConfiguration()->ReadParameter( useFastAndLowMemoryVersion,
      "UseFastAndLowMemoryVersion", this->GetComponentLabel(), level, 0 );
    this->SetUseExplicitPDFDerivatives( !useFastAndLowMemoryVersion );

    /** Set whether a finite difference derivative should be used. */
    bool useFiniteDifferenceDerivative = false;
    this->GetConfiguration()->ReadParameter( useFiniteDifferenceDerivative,
      "FiniteDifferenceDerivative", this->GetComponentLabel(), level, 0 );
    this->SetUseFiniteDifferenceDerivative( useFiniteDifferenceDerivative );

    /** Prepare for computing the perturbation gain c_k. */
    this->SetCurrentIteration( 0 );
    if ( useFiniteDifferenceDerivative )
    {
      double c = 1.0;
      double gamma = 0.101;
      this->GetConfiguration()->ReadParameter(c, "SP_c", this->GetComponentLabel(), level, 0 );
      this->GetConfiguration()->ReadParameter(gamma, "SP_gamma", this->GetComponentLabel(), level, 0 );
      this->SetParam_c( c );
      this->SetParam_gamma( gamma );
      this->SetFiniteDifferencePerturbation( this->Compute_c( 0 ) );
    }

    this->SetUseMovingImageDerivativeScales( false );
    MovingImageDerivativeScalesType movingImageDerivativeScales;
    int usescales = 0;
    for ( unsigned int i = 0; i < MovingImageDimension; ++i )
    {
      usescales |= this->GetConfiguration()->ReadParameter( movingImageDerivativeScales[i],
        "MovingImageDerivativeScales", this->GetComponentLabel(), i, -1, true );
    }
    if ( usescales == 0 )
    {
      this->SetUseMovingImageDerivativeScales( true );
      this->SetMovingImageDerivativeScales( movingImageDerivativeScales );
      elxout << "Multiplying moving image derivatives by: " << movingImageDerivativeScales << std::endl;
    }

  } // end BeforeEachResolution()

  /**
   * ***************** AfterEachIteration ***********************
   */

  template <class TElastix>
    void AdvancedMattesMutualInformationMetric<TElastix>
    ::AfterEachIteration(void)
  {
    if ( this->GetUseFiniteDifferenceDerivative() )
    {
      this->m_CurrentIteration++;
      this->SetFiniteDifferencePerturbation(
        this->Compute_c( this->m_CurrentIteration )  );
    }
  }  // end AfterEachIteration()

  /**
   * ************************** Compute_c *************************
   *
   * This function computes the parameter a at iteration k, as
   * in the finite difference optimizer.
   */

  template <class TElastix>
    double AdvancedMattesMutualInformationMetric<TElastix>
    ::Compute_c( unsigned long k ) const
  {
    return static_cast<double>(
      this->m_Param_c / vcl_pow( k + 1, this->m_Param_gamma ) );

  } // end Compute_c()

} // end namespace elastix

#endif // end #ifndef __elxAdvancedMattesMutualInformationMetric_HXX__
<commit_msg>MS:<commit_after>/*======================================================================

  This file is part of the elastix software.

  Copyright (c) University Medical Center Utrecht. All rights reserved.
  See src/CopyrightElastix.txt or http://elastix.isi.uu.nl/legal.php 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.

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

#ifndef __elxAdvancedMattesMutualInformationMetric_HXX__
#define __elxAdvancedMattesMutualInformationMetric_HXX__

#include "elxAdvancedMattesMutualInformationMetric.h"
#include "itkHardLimiterFunction.h"
#include "itkExponentialLimiterFunction.h"
#include <string>
#include "vnl/vnl_math.h"

namespace elastix
{
using namespace itk;

  /**
   * ****************** Constructor ***********************
   */

  template <class TElastix>
    AdvancedMattesMutualInformationMetric<TElastix>
    ::AdvancedMattesMutualInformationMetric()
  {
    this->m_Param_c = 1.0;
    this->m_Param_gamma = 0.101;
    this->SetUseDerivative( true );

  } // end Constructor()

  /**
   * ******************* Initialize ***********************
   */

  template <class TElastix>
    void AdvancedMattesMutualInformationMetric<TElastix>
    ::Initialize( void ) throw (ExceptionObject)
  {
    TimerPointer timer = TimerType::New();
    timer->StartTimer();
    this->Superclass1::Initialize();
    timer->StopTimer();
    elxout << "Initialization of AdvancedMattesMutualInformation metric took: "
      << static_cast<long>( timer->GetElapsedClockSec() * 1000 ) << " ms." << std::endl;

  } // end Initialize()

  /**
   * ***************** BeforeEachResolution ***********************
   */

  template <class TElastix>
    void AdvancedMattesMutualInformationMetric<TElastix>
    ::BeforeEachResolution( void )
  {
    /** Get the current resolution level. */
    unsigned int level =
      ( this->m_Registration->GetAsITKBaseType() )->GetCurrentLevel();

    /** Get and set the number of histogram bins. */
    unsigned int numberOfHistogramBins = 32;
    this->GetConfiguration()->ReadParameter( numberOfHistogramBins,
      "NumberOfHistogramBins", this->GetComponentLabel(), level, 0 );
    this->SetNumberOfFixedHistogramBins( numberOfHistogramBins );
    this->SetNumberOfMovingHistogramBins( numberOfHistogramBins );

    unsigned int numberOfFixedHistogramBins = numberOfHistogramBins;
    unsigned int numberOfMovingHistogramBins = numberOfHistogramBins;
    this->GetConfiguration()->ReadParameter( numberOfFixedHistogramBins,
      "NumberOfFixedHistogramBins", this->GetComponentLabel(), level, 0 );
    this->GetConfiguration()->ReadParameter( numberOfMovingHistogramBins,
      "NumberOfMovingHistogramBins", this->GetComponentLabel(), level, 0 );
    this->SetNumberOfFixedHistogramBins( numberOfFixedHistogramBins );
    this->SetNumberOfMovingHistogramBins( numberOfMovingHistogramBins );

    /** Set limiters. */
    typedef HardLimiterFunction< RealType, FixedImageDimension > FixedLimiterType;
    typedef ExponentialLimiterFunction< RealType, MovingImageDimension > MovingLimiterType;
    this->SetFixedImageLimiter( FixedLimiterType::New() );
    this->SetMovingImageLimiter( MovingLimiterType::New() );

    /** Get and set the limit range ratios. */
    double fixedLimitRangeRatio = 0.01;
    double movingLimitRangeRatio = 0.01;
    this->GetConfiguration()->ReadParameter( fixedLimitRangeRatio,
      "FixedLimitRangeRatio", this->GetComponentLabel(), level, 0 );
    this->GetConfiguration()->ReadParameter( movingLimitRangeRatio,
      "MovingLimitRangeRatio", this->GetComponentLabel(), level, 0 );
    this->SetFixedLimitRangeRatio( fixedLimitRangeRatio );
    this->SetMovingLimitRangeRatio( movingLimitRangeRatio );

    /** Set B-spline Parzen kernel orders. */
    unsigned int fixedKernelBSplineOrder = 0;
    unsigned int movingKernelBSplineOrder = 3;
    this->GetConfiguration()->ReadParameter( fixedKernelBSplineOrder,
      "FixedKernelBSplineOrder", this->GetComponentLabel(), level, 0 );
    this->GetConfiguration()->ReadParameter( movingKernelBSplineOrder,
      "MovingKernelBSplineOrder", this->GetComponentLabel(), level, 0 );
    this->SetFixedKernelBSplineOrder( fixedKernelBSplineOrder );
    this->SetMovingKernelBSplineOrder( movingKernelBSplineOrder );

    /** Set whether a low memory consumption should be used. */
    bool useFastAndLowMemoryVersion = true;
    this->GetConfiguration()->ReadParameter( useFastAndLowMemoryVersion,
      "UseFastAndLowMemoryVersion", this->GetComponentLabel(), level, 0 );
    this->SetUseExplicitPDFDerivatives( !useFastAndLowMemoryVersion );

    /** Set whether a finite difference derivative should be used. */
    bool useFiniteDifferenceDerivative = false;
    this->GetConfiguration()->ReadParameter( useFiniteDifferenceDerivative,
      "FiniteDifferenceDerivative", this->GetComponentLabel(), level, 0 );
    this->SetUseFiniteDifferenceDerivative( useFiniteDifferenceDerivative );

    /** Prepare for computing the perturbation gain c_k. */
    this->SetCurrentIteration( 0 );
    if ( useFiniteDifferenceDerivative )
    {
      double c = 1.0;
      double gamma = 0.101;
      this->GetConfiguration()->ReadParameter( c, "SP_c",
        this->GetComponentLabel(), level, 0 );
      this->GetConfiguration()->ReadParameter( gamma, "SP_gamma",
        this->GetComponentLabel(), level, 0 );
      this->SetParam_c( c );
      this->SetParam_gamma( gamma );
      this->SetFiniteDifferencePerturbation( this->Compute_c( 0 ) );
    }

    this->SetUseMovingImageDerivativeScales( false );
    MovingImageDerivativeScalesType movingImageDerivativeScales;
    int usescales = 0;
    for ( unsigned int i = 0; i < MovingImageDimension; ++i )
    {
      usescales |= this->GetConfiguration()->ReadParameter(
        movingImageDerivativeScales[ i ], "MovingImageDerivativeScales",
        this->GetComponentLabel(), i, -1, true );
    }
    if ( usescales == 0 )
    {
      this->SetUseMovingImageDerivativeScales( true );
      this->SetMovingImageDerivativeScales( movingImageDerivativeScales );
      elxout << "Multiplying moving image derivatives by: "
        << movingImageDerivativeScales << std::endl;
    }

  } // end BeforeEachResolution()

  /**
   * ***************** AfterEachIteration ***********************
   */

  template <class TElastix>
    void AdvancedMattesMutualInformationMetric<TElastix>
    ::AfterEachIteration(void)
  {
    if ( this->GetUseFiniteDifferenceDerivative() )
    {
      this->m_CurrentIteration++;
      this->SetFiniteDifferencePerturbation(
        this->Compute_c( this->m_CurrentIteration )  );
    }
  }  // end AfterEachIteration()

  /**
   * ************************** Compute_c *************************
   *
   * This function computes the parameter a at iteration k, as
   * in the finite difference optimizer.
   */

  template <class TElastix>
    double AdvancedMattesMutualInformationMetric<TElastix>
    ::Compute_c( unsigned long k ) const
  {
    return static_cast<double>(
      this->m_Param_c / vcl_pow( k + 1, this->m_Param_gamma ) );

  } // end Compute_c()

} // end namespace elastix

#endif // end #ifndef __elxAdvancedMattesMutualInformationMetric_HXX__
<|endoftext|>


<commit_before>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005 darkbits                        Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

#include "config.hpp"

extern "C"
{
  char* gcnGuichanVersion()
  {
    return PACKAGE_VERSION;
  }
}
<commit_msg>Removed #include "config.hpp".<commit_after>/*      _______   __   __   __   ______   __   __   _______   __   __
 *     / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___  /\ /  |\/ /\
 *    / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
 *   / / /__   / / // / // / // / /    / ___  / // ___  / // /| ' / /
 *  / /_// /\ / /_// / // / // /_/_   / / // / // /\_/ / // / |  / /
 * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
 * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
 *
 * Copyright (c) 2004, 2005 darkbits                        Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of Guichan nor the      :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * 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.
 */

/*
 * For comments regarding functions please see the header file.
 */

extern "C"
{
  char* gcnGuichanVersion()
  {
    return "0.3.0";
  }
}
<|endoftext|>


<commit_before>/*!
  \copyright (c) RDO-Team, 2009-2012
  \file      main.cpp
  \author      (rdo@rk9.bmstu.ru)
  \date      01.05.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#define BOOST_TEST_MODULE RDOCalc_Test
#include <boost/test/included/unit_test.hpp>
#include <boost/tuple/tuple.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/calc/procedural/calc_const.h"
#include "simulator/runtime/calc/procedural/calc_statement.h"
#include "simulator/runtime/calc/operation/calc_arithm.h"
#include "simulator/runtime/calc/operation/calc_logic.h"
#include "simulator/runtime/calc/function/calc_function.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

BOOST_AUTO_TEST_SUITE(RDOCalc_Test)

static const double const1 = 10.5;
static const double const2 = 11.4;

typedef  boost::tuple<LPRDORuntime, LPRDOCalc, LPRDOCalc>  CalcPair;

template <class T>
RDOValue calc(CREF(CalcPair) calcPair)
{
	BOOST_CHECK(calcPair.get<0>());
	BOOST_CHECK(calcPair.get<1>());
	BOOST_CHECK(calcPair.get<2>());

	rdo::intrusive_ptr<T> pCalc = rdo::Factory<T>::create(calcPair.get<1>(), calcPair.get<2>());
	ASSERT(pCalc);

	return pCalc->calcValue(calcPair.get<0>());
}

CalcPair prepair()
{
	LPRDORuntime pRuntime = rdo::Factory<RDORuntime>::create();
	BOOST_CHECK(pRuntime);

	LPRDOCalc pLeft = rdo::Factory<RDOCalcConst>::create(RDOValue(const1));
	BOOST_CHECK(pLeft);

	LPRDOCalc pRight = rdo::Factory<RDOCalcConst>::create(RDOValue(const2));
	BOOST_CHECK(pRight);

	return CalcPair(pRuntime, pLeft, pRight);
}

BOOST_AUTO_TEST_CASE(RDOCalc_MultDouble)
{
	RDOValue result = calc<RDOCalcMult>(prepair());
	BOOST_CHECK(result.getDouble() == const1 * const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_DivDouble)
{
	RDOValue result = calc<RDOCalcDiv>(prepair());
	BOOST_CHECK(result.getDouble() == const1 / const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_PlusDouble)
{
	RDOValue result = calc<RDOCalcPlus>(prepair());
	BOOST_CHECK(result.getDouble() == const1 + const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_MinusDouble)
{
	RDOValue result = calc<RDOCalcMinus>(prepair());
	BOOST_CHECK(result.getDouble() == const1 - const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_RecursSimulator)
{
	struct RecursCalcSimulator
	{
		struct Param
		{
			Param(int value)
				: m_value(value)
			{}

			//! ,    int,   int&
			//!       1
			//!   1  120
			int value()
			{
				return m_value;
			}

			Param& dec()
			{
				--m_value;
				return *this;
			}

		private:
			int m_value;
		};

		int funError(Param& param)
		{
			if (param.value() == 1)
			{
				return 1;
			}
			else
			{
				return funError(param.dec()) * param.value();
			}
		}

		int funOk(Param& param)
		{
			if (param.value() == 1)
			{
				return 1;
			}
			else
			{
				return param.value() * funOk(param.dec());
			}
		}
	};

	RecursCalcSimulator calc1;
	RecursCalcSimulator calc2;
	RecursCalcSimulator::Param param1(5);
	RecursCalcSimulator::Param param2(5);

	int resultError = calc1.funError(param1);
	int resultOk    = calc2.funOk   (param2);
	BOOST_CHECK(resultError == 1);
	BOOST_CHECK(resultOk    == 120);
}

BOOST_AUTO_TEST_CASE(RDOCalc_Recurs)
{
	struct generator
	{
		enum MultOrder
		{
			MO_FUN_PARAM,
			MO_PARAM_FUN
		};

		static LPRDOCalc create(MultOrder order)
		{
			//!
			//!
			//! int fun(int param)
			//! {
			//!     if (param == 1)
			//!     {
			//!        return 1;
			//!     }
			//!     else
			//!     {
			//!        return fun(param - 1) * param;
			//!     }
			//! }

			LPRDOCalcReturnCatch pReturnCatch = rdo::Factory<RDOCalcReturnCatch>::create();
			BOOST_CHECK(pReturnCatch);

			LPRDOCalc pGetFunParam = rdo::Factory<RDOCalcFuncParam>::create(0, RDOSrcInfo());

			//! if (param == 1)
			LPRDOCalc pIFCondition;
			{
				LPRDOCalc pParamLeft = pGetFunParam;
				BOOST_CHECK(pParamLeft);

				LPRDOCalc pParamRight = rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(1)));
				BOOST_CHECK(pParamRight);

				pIFCondition = rdo::Factory<RDOCalcIsEqual>::create(pParamLeft, pParamRight);
			}
			BOOST_CHECK(pIFCondition);

			LPRDOCalcIf pIf = rdo::Factory<RDOCalcIf>::create(pIFCondition);
			BOOST_CHECK(pIf);

			//! return 1
			LPRDOCalc pThen = rdo::Factory<RDOCalcFunReturn>::create(
				rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(1)))
			);
			BOOST_CHECK(pThen);

			//! return fun(param - 1) * param
			LPRDOCalc pElse;
			{
				//! param - 1
				LPRDOCalc pParamValue;
				{
					LPRDOCalc pParamLeft = pGetFunParam;
					BOOST_CHECK(pParamLeft);

					LPRDOCalc pParamRight = rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(1)));
					BOOST_CHECK(pParamRight);

					pParamValue = rdo::Factory<RDOCalcMinus>::create(pParamLeft, pParamRight);
				}
				BOOST_CHECK(pParamValue);

				//!  fun(param - 1)
				LPRDOCalc pFunctionCaller = caller(pReturnCatch, pParamValue);
				BOOST_CHECK(pFunctionCaller);

				//! fun(param - 1) * param
				//!
				//! param * fun(param - 1)
				LPRDOCalc pMult;
				switch (order)
				{
				case MO_FUN_PARAM: pMult = rdo::Factory<RDOCalcMult>::create(pFunctionCaller, pGetFunParam); break;
				case MO_PARAM_FUN: pMult = rdo::Factory<RDOCalcMult>::create(pGetFunParam, pFunctionCaller); break;
				}
				BOOST_CHECK(pMult);

				pElse = rdo::Factory<RDOCalcFunReturn>::create(pMult);
			}
			BOOST_CHECK(pElse);

			pIf->setThenStatement(pThen);
			pIf->setElseStatement(pElse);

			pReturnCatch->setTryCalc(pIf);

			return externalCaller(pReturnCatch);
		}

	private:
		//!     int fun(5)
		static LPRDOCalc externalCaller(CREF(LPRDOCalc) pBody)
		{
			LPRDOCalc pParam = rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(5)));
			BOOST_CHECK(pParam);

			return caller(pBody, pParam);
		}

		static LPRDOCalc caller(CREF(LPRDOCalc) pBody, CREF(LPRDOCalc) pParam)
		{
			BOOST_CHECK(pBody );
			BOOST_CHECK(pParam);

			LPRDOCalcFunctionCaller pFunctionCaller = rdo::Factory<RDOCalcFunctionCaller>::create(pBody);
			BOOST_CHECK(pFunctionCaller);

			pFunctionCaller->addParameter(pParam);

			return pFunctionCaller;
		}
	};

	RDOValue resultFunParam = generator::create(generator::MO_FUN_PARAM)->calcValue(rdo::Factory<RDORuntime>::create());
	tstring resultFunParamStr = resultFunParam.getAsString();
	BOOST_CHECK(resultFunParam.getInt() == 120);

	RDOValue resultParamFun = generator::create(generator::MO_PARAM_FUN)->calcValue(rdo::Factory<RDORuntime>::create());
	tstring resultParamFunStr = resultParamFun.getAsString();
	BOOST_CHECK(resultParamFun.getInt() == 120);
}

BOOST_AUTO_TEST_SUITE_END() // RDOCalc_Test

CLOSE_RDO_RUNTIME_NAMESPACE
<commit_msg> - добавлен тест скорости<commit_after>/*!
  \copyright (c) RDO-Team, 2009-2012
  \file      main.cpp
  \author      (rdo@rk9.bmstu.ru)
  \date      01.05.2012
  \brief
  \indent    4T
*/

// ---------------------------------------------------------------------------- PCH
// ----------------------------------------------------------------------- INCLUDES
#define BOOST_TEST_MODULE RDOCalc_Test
#include <boost/test/included/unit_test.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/chrono.hpp>
// ----------------------------------------------------------------------- SYNOPSIS
#include "simulator/runtime/rdo_runtime.h"
#include "simulator/runtime/calc/procedural/calc_const.h"
#include "simulator/runtime/calc/procedural/calc_statement.h"
#include "simulator/runtime/calc/operation/calc_arithm.h"
#include "simulator/runtime/calc/operation/calc_logic.h"
#include "simulator/runtime/calc/function/calc_function.h"
// --------------------------------------------------------------------------------

OPEN_RDO_RUNTIME_NAMESPACE

BOOST_AUTO_TEST_SUITE(RDOCalc_Test)

static const double const1 = 10.5;
static const double const2 = 11.4;

typedef  boost::tuple<LPRDORuntime, LPRDOCalc, LPRDOCalc>  CalcTriple;

template <class T>
RDOValue calc(CREF(CalcTriple) calcTriple)
{
	BOOST_CHECK(calcTriple.get<0>());
	BOOST_CHECK(calcTriple.get<1>());
	BOOST_CHECK(calcTriple.get<2>());

	rdo::intrusive_ptr<T> pCalc = rdo::Factory<T>::create(calcTriple.get<1>(), calcTriple.get<2>());
	ASSERT(pCalc);

	return pCalc->calcValue(calcTriple.get<0>());
}

CalcTriple prepair()
{
	LPRDORuntime pRuntime = rdo::Factory<RDORuntime>::create();
	BOOST_CHECK(pRuntime);

	LPRDOCalc pLeft = rdo::Factory<RDOCalcConst>::create(RDOValue(const1));
	BOOST_CHECK(pLeft);

	LPRDOCalc pRight = rdo::Factory<RDOCalcConst>::create(RDOValue(const2));
	BOOST_CHECK(pRight);

	return CalcTriple(pRuntime, pLeft, pRight);
}

BOOST_AUTO_TEST_CASE(RDOCalc_MultDouble)
{
	RDOValue result = calc<RDOCalcMult>(prepair());
	BOOST_CHECK(result.getDouble() == const1 * const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_DivDouble)
{
	RDOValue result = calc<RDOCalcDiv>(prepair());
	BOOST_CHECK(result.getDouble() == const1 / const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_PlusDouble)
{
	RDOValue result = calc<RDOCalcPlus>(prepair());
	BOOST_CHECK(result.getDouble() == const1 + const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_MinusDouble)
{
	RDOValue result = calc<RDOCalcMinus>(prepair());
	BOOST_CHECK(result.getDouble() == const1 - const2);
}

BOOST_AUTO_TEST_CASE(RDOCalc_RecursSimulator)
{
	struct RecursCalcSimulator
	{
		struct Param
		{
			Param(int value)
				: m_value(value)
			{}

			//! ,    int,   int&
			//!       1
			//!   1  120
			int value()
			{
				return m_value;
			}

			Param& dec()
			{
				--m_value;
				return *this;
			}

		private:
			int m_value;
		};

		int funError(Param& param)
		{
			if (param.value() == 1)
			{
				return 1;
			}
			else
			{
				return funError(param.dec()) * param.value();
			}
		}

		int funOk(Param& param)
		{
			if (param.value() == 1)
			{
				return 1;
			}
			else
			{
				return param.value() * funOk(param.dec());
			}
		}
	};

	RecursCalcSimulator calc1;
	RecursCalcSimulator calc2;
	RecursCalcSimulator::Param param1(5);
	RecursCalcSimulator::Param param2(5);

	int resultError = calc1.funError(param1);
	int resultOk    = calc2.funOk   (param2);
	BOOST_CHECK(resultError == 1);
	BOOST_CHECK(resultOk    == 120);
}

BOOST_AUTO_TEST_CASE(RDOCalc_Recurs)
{
	struct generator
	{
		enum MultOrder
		{
			MO_FUN_PARAM,
			MO_PARAM_FUN
		};

		static LPRDOCalc create(MultOrder order)
		{
			//!
			//!
			//! int fun(int param)
			//! {
			//!     if (param == 1)
			//!     {
			//!        return 1;
			//!     }
			//!     else
			//!     {
			//!        return fun(param - 1) * param;
			//!     }
			//! }

			LPRDOCalcReturnCatch pReturnCatch = rdo::Factory<RDOCalcReturnCatch>::create();
			BOOST_CHECK(pReturnCatch);

			LPRDOCalc pGetFunParam = rdo::Factory<RDOCalcFuncParam>::create(0, RDOSrcInfo());

			//! if (param == 1)
			LPRDOCalc pIFCondition;
			{
				LPRDOCalc pParamLeft = pGetFunParam;
				BOOST_CHECK(pParamLeft);

				LPRDOCalc pParamRight = rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(1)));
				BOOST_CHECK(pParamRight);

				pIFCondition = rdo::Factory<RDOCalcIsEqual>::create(pParamLeft, pParamRight);
			}
			BOOST_CHECK(pIFCondition);

			LPRDOCalcIf pIf = rdo::Factory<RDOCalcIf>::create(pIFCondition);
			BOOST_CHECK(pIf);

			//! return 1
			LPRDOCalc pThen = rdo::Factory<RDOCalcFunReturn>::create(
				rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(1)))
			);
			BOOST_CHECK(pThen);

			//! return fun(param - 1) * param
			LPRDOCalc pElse;
			{
				//! param - 1
				LPRDOCalc pParamValue;
				{
					LPRDOCalc pParamLeft = pGetFunParam;
					BOOST_CHECK(pParamLeft);

					LPRDOCalc pParamRight = rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(1)));
					BOOST_CHECK(pParamRight);

					pParamValue = rdo::Factory<RDOCalcMinus>::create(pParamLeft, pParamRight);
				}
				BOOST_CHECK(pParamValue);

				//!  fun(param - 1)
				LPRDOCalc pFunctionCaller = caller(pReturnCatch, pParamValue);
				BOOST_CHECK(pFunctionCaller);

				//! fun(param - 1) * param
				//!
				//! param * fun(param - 1)
				LPRDOCalc pMult;
				switch (order)
				{
				case MO_FUN_PARAM: pMult = rdo::Factory<RDOCalcMult>::create(pFunctionCaller, pGetFunParam); break;
				case MO_PARAM_FUN: pMult = rdo::Factory<RDOCalcMult>::create(pGetFunParam, pFunctionCaller); break;
				}
				BOOST_CHECK(pMult);

				pElse = rdo::Factory<RDOCalcFunReturn>::create(pMult);
			}
			BOOST_CHECK(pElse);

			pIf->setThenStatement(pThen);
			pIf->setElseStatement(pElse);

			pReturnCatch->setTryCalc(pIf);

			return externalCaller(pReturnCatch);
		}

	private:
		//!     int fun(5)
		static LPRDOCalc externalCaller(CREF(LPRDOCalc) pBody)
		{
			LPRDOCalc pParam = rdo::Factory<RDOCalcConst>::create(RDOValue(rsint(5)));
			BOOST_CHECK(pParam);

			return caller(pBody, pParam);
		}

		static LPRDOCalc caller(CREF(LPRDOCalc) pBody, CREF(LPRDOCalc) pParam)
		{
			BOOST_CHECK(pBody );
			BOOST_CHECK(pParam);

			LPRDOCalcFunctionCaller pFunctionCaller = rdo::Factory<RDOCalcFunctionCaller>::create(pBody);
			BOOST_CHECK(pFunctionCaller);

			pFunctionCaller->addParameter(pParam);

			return pFunctionCaller;
		}
	};

	RDOValue resultFunParam = generator::create(generator::MO_FUN_PARAM)->calcValue(rdo::Factory<RDORuntime>::create());
	tstring resultFunParamStr = resultFunParam.getAsString();
	BOOST_CHECK(resultFunParam.getInt() == 120);

	RDOValue resultParamFun = generator::create(generator::MO_PARAM_FUN)->calcValue(rdo::Factory<RDORuntime>::create());
	tstring resultParamFunStr = resultParamFun.getAsString();
	BOOST_CHECK(resultParamFun.getInt() == 120);
}

BOOST_AUTO_TEST_CASE(RDOCalc_SpeedTest)
{
	CalcTriple triple = prepair();
	LPRDOCalc pPlus = rdo::Factory<RDOCalcPlus>::create(triple.get<1>(), triple.get<2>());
	BOOST_CHECK(pPlus);

	LPRDORuntime pRuntime = triple.get<0>();
	BOOST_CHECK(pRuntime);

	typedef  boost::chrono::process_user_cpu_clock  clock;

	static const ruint RUN_TEST_COUNT = 1000000;

	clock::time_point timeStart = clock::now();
	for (ruint i = 0; i < RUN_TEST_COUNT; ++i)
	{
		pPlus->calcValue(pRuntime);
	}
	clock::duration duration(clock::now() - timeStart);

	{
		using namespace boost::unit_test;
		log_level logLevelBackup = runtime_config::log_level();
		unit_test_log.set_threshold_level(log_messages);

		BOOST_TEST_MESSAGE(_T("RDOCalc_SpeedTest: ") << duration);

		unit_test_log.set_threshold_level(logLevelBackup);
	}
}

BOOST_AUTO_TEST_SUITE_END() // RDOCalc_Test

CLOSE_RDO_RUNTIME_NAMESPACE
<|endoftext|>


<commit_before>/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <vector>
#include "kernel/kernel_exception.h"

namespace lean {
format kernel_exception::pp(formatter const &, options const &) const {
    return format(what());
}

format unknown_name_exception::pp(formatter const &, options const &) const {
    return format{format("unknown object '"), format(get_name()), format("'")};
}

format already_declared_exception::pp(formatter const &, options const &) const {
    return format{format("invalid object declaration, environment already has an object named '"), format(get_name()), format("'")};
}

format has_no_type_exception::pp(formatter const &, options const &) const {
    return format{format("object '"), format(const_name(m_const)), format("' has no type associated with it")};
}

format app_type_mismatch_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent     = get_pp_indent(opts);
    context const & ctx = get_context();
    expr const & app    = get_application();
    format app_fmt      = fmt(ctx, app, false, opts);
    std::vector<expr> const & arg_types = get_arg_types();
    auto it = arg_types.begin();
    format f_type_fmt   = fmt(ctx, *it, false, opts);
    format arg_types_fmt;
    ++it;
    for (unsigned i = 1; it != arg_types.end(); ++it, ++i) {
        expr const & a    = arg(app, i);
        format arg_fmt    = fmt(ctx, a, false, opts);
        if (is_pi(a) || is_lambda(a) || is_let(a))
            arg_fmt = paren(arg_fmt);
        format arg_type_fmt = fmt(ctx, *it, false, opts);
        arg_types_fmt += nest(indent, compose(line(), group(format{arg_fmt, space(), colon(), nest(indent, format{line(), arg_type_fmt})})));
    }
    format r;
    r += format("type mismatch at application");
    r += nest(indent, compose(line(), app_fmt));
    r += compose(line(), format("Function type:"));
    r += nest(indent, compose(line(), f_type_fmt));
    r += line();
    if (arg_types.size() > 2)
        r += format("Arguments types:");
    else
        r += format("Argument type:");
    r += arg_types_fmt;
    return r;
}

format function_expected_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent = get_pp_indent(opts);
    format expr_fmt = fmt(get_context(), get_expr(), false, opts);
    format r;
    r += format("function expected at");
    r += nest(indent, compose(line(), expr_fmt));
    return r;
}

format type_expected_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent = get_pp_indent(opts);
    format expr_fmt = fmt(get_context(), get_expr(), false, opts);
    format r;
    r += format("type expected, got");
    r += nest(indent, compose(line(), expr_fmt));
    return r;
}

format def_type_mismatch_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent     = get_pp_indent(opts);
    context const & ctx = get_context();
    format r;
    r += format("type mismatch at definition '");
    r += format(get_name());
    r += format("', expected type");
    r += nest(indent, compose(line(), fmt(ctx, get_type(), false, opts)));
    r += compose(line(), format("Given type:"));
    r += nest(indent, compose(line(), fmt(ctx, get_value_type(), false, opts)));
    return r;
}
}
<commit_msg>fix(kernel/kernel_exception): incorrect pp method<commit_after>/*
Copyright (c) 2013 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <vector>
#include "kernel/kernel_exception.h"

namespace lean {
format kernel_exception::pp(formatter const &, options const &) const {
    return format(what());
}

format unknown_name_exception::pp(formatter const &, options const &) const {
    return format{format(what()), format(" '"), format(get_name()), format("'")};
}

format already_declared_exception::pp(formatter const &, options const &) const {
    return format{format("invalid object declaration, environment already has an object named '"), format(get_name()), format("'")};
}

format has_no_type_exception::pp(formatter const &, options const &) const {
    return format{format("object '"), format(const_name(m_const)), format("' has no type associated with it")};
}

format app_type_mismatch_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent     = get_pp_indent(opts);
    context const & ctx = get_context();
    expr const & app    = get_application();
    format app_fmt      = fmt(ctx, app, false, opts);
    std::vector<expr> const & arg_types = get_arg_types();
    auto it = arg_types.begin();
    format f_type_fmt   = fmt(ctx, *it, false, opts);
    format arg_types_fmt;
    ++it;
    for (unsigned i = 1; it != arg_types.end(); ++it, ++i) {
        expr const & a    = arg(app, i);
        format arg_fmt    = fmt(ctx, a, false, opts);
        if (is_pi(a) || is_lambda(a) || is_let(a))
            arg_fmt = paren(arg_fmt);
        format arg_type_fmt = fmt(ctx, *it, false, opts);
        arg_types_fmt += nest(indent, compose(line(), group(format{arg_fmt, space(), colon(), nest(indent, format{line(), arg_type_fmt})})));
    }
    format r;
    r += format("type mismatch at application");
    r += nest(indent, compose(line(), app_fmt));
    r += compose(line(), format("Function type:"));
    r += nest(indent, compose(line(), f_type_fmt));
    r += line();
    if (arg_types.size() > 2)
        r += format("Arguments types:");
    else
        r += format("Argument type:");
    r += arg_types_fmt;
    return r;
}

format function_expected_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent = get_pp_indent(opts);
    format expr_fmt = fmt(get_context(), get_expr(), false, opts);
    format r;
    r += format("function expected at");
    r += nest(indent, compose(line(), expr_fmt));
    return r;
}

format type_expected_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent = get_pp_indent(opts);
    format expr_fmt = fmt(get_context(), get_expr(), false, opts);
    format r;
    r += format("type expected, got");
    r += nest(indent, compose(line(), expr_fmt));
    return r;
}

format def_type_mismatch_exception::pp(formatter const & fmt, options const & opts) const {
    unsigned indent     = get_pp_indent(opts);
    context const & ctx = get_context();
    format r;
    r += format("type mismatch at definition '");
    r += format(get_name());
    r += format("', expected type");
    r += nest(indent, compose(line(), fmt(ctx, get_type(), false, opts)));
    r += compose(line(), format("Given type:"));
    r += nest(indent, compose(line(), fmt(ctx, get_value_type(), false, opts)));
    return r;
}
}
<|endoftext|>


<commit_before>#include "Loop.h"

Loop* Loop::loopInstance = nullptr;
int CallbackData::idCount = 0;

void Loop::process()
{
	for(auto timeout : timeouts)
	{
		if( millis() - timeout->started() > timeout->delay() )
		{
			// call the timeout
			timeout->callback()();
			timeout->reset();
		}
	}
}

int Loop::addTimeout(unsigned long delay, CallbackData::Callback cb)
{
	CallbackData* cbd = new CallbackData(delay, cb);

	timeouts.push_back(cbd);

	return cbd->id();
}

void Loop::removeTimeout(int hndl)
{
	for(auto itr = timeouts.begin(); itr < timeouts.end();  itr++)
	{
		auto timeout = *itr;

		if(timeout->id() == hndl)
		{
			timeouts.erase(itr);
			delete timeout;
		}
	}
}<commit_msg>fixed more error<commit_after>#include "Loop.h"

Loop* Loop::loopInstance = nullptr;
int CallbackData::idCount = 0;

void Loop::process()
{
	for(auto timeout : timeouts)
	{
		if( millis() - timeout->started() > timeout->delay() )
		{
			// call the timeout
			timeout->callback()();
			timeout->reset();
		}
	}
}

int Loop::addTimeout(unsigned long delay, CallbackData::Callback cb)
{
	CallbackData* cbd = new CallbackData(delay, cb);

	timeouts.push_back(cbd);

	return cbd->id();
}

void Loop::removeTimeout(int hndl)
{
	for(auto itr = timeouts.begin(); itr != timeouts.end();  itr++)
	{
		auto timeout = *itr;

		if(timeout->id() == hndl)
		{
			timeouts.erase(itr);
			delete timeout;
		}
	}
}<|endoftext|>


<commit_before>/* libwpd2
 * Copyright (C) 2002 William Lachance (wlach@interlog.com)
 * Copyright (C) 2002 Marc Maurer (j.m.maurer@student.utwente.nl)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * For further information visit http://libwpd.sourceforge.net
 */

/* "This product is not manufactured, approved, or supported by
 * Corel Corporation or Corel Corporation Limited."
 */

#include "WP6FixedLengthGroup.h"

#include "WP6FixedSpaceGroup.h"
#include "WP6FixedEOLGroup.h"
#include "WP6ExtendedCharacterGroup.h"
#include "WP6UndoGroup.h"
#include "WP6AttributeOnGroup.h"
#include "WP6AttributeOffGroup.h"

WP6FixedLengthGroup * WP6FixedLengthGroup::constructFixedLengthGroup(FILE *stream, guint8 groupID)
{
	switch (groupID)
		{

		case WP6_TOP_SOFT_EOL:
		case WP6_TOP_SOFT_SPACE:
			return new WP6FixedSpaceGroup(stream);

		case WP6_TOP_HARD_EOL:
		case WP6_TOP_DORMANT_HARD_RETURN:
			return new WP6FixedEOLGroup(stream);

		case WP6_TOP_EXTENDED_CHARACTER:
			return new WP6ExtendedCharacterGroup(stream);

		case WP6_TOP_UNDO_GROUP:
			return new WP6UndoGroup(stream);

		case WP6_TOP_ATTRIBUTE_ON:
			return new WP6AttributeOnGroup(stream);

		case WP6_TOP_ATTRIBUTE_OFF:
			return new WP6AttributeOffGroup(stream);

		// Add the remaining cases here
		default:
			// should not happen
			return NULL;
	}
}

gboolean WP6FixedLengthGroup::_read(FILE *stream, guint size)
{
	guint32 startPosition = ftell(stream);
	WPD_CHECK_INTERNAL_ERROR(_readContents(stream));
	WPD_CHECK_FILE_SEEK_ERROR(fseek(stream, (startPosition + size - 1 - ftell(stream)), SEEK_CUR));
}
<commit_msg>- minor correction<commit_after>/* libwpd2
 * Copyright (C) 2002 William Lachance (wlach@interlog.com)
 * Copyright (C) 2002 Marc Maurer (j.m.maurer@student.utwente.nl)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * For further information visit http://libwpd.sourceforge.net
 */

/* "This product is not manufactured, approved, or supported by
 * Corel Corporation or Corel Corporation Limited."
 */

#include "WP6FixedLengthGroup.h"

#include "WP6FixedSpaceGroup.h"
#include "WP6FixedEOLGroup.h"
#include "WP6ExtendedCharacterGroup.h"
#include "WP6UndoGroup.h"
#include "WP6AttributeGroup.h"

WP6FixedLengthGroup * WP6FixedLengthGroup::constructFixedLengthGroup(FILE *stream, guint8 groupID)
{
	switch (groupID)
		{

		case WP6_TOP_SOFT_EOL:
		case WP6_TOP_SOFT_SPACE:
			return new WP6FixedSpaceGroup(stream);

		case WP6_TOP_HARD_EOL:
		case WP6_TOP_DORMANT_HARD_RETURN:
			return new WP6FixedEOLGroup(stream);

		case WP6_TOP_EXTENDED_CHARACTER:
			return new WP6ExtendedCharacterGroup(stream);

		case WP6_TOP_UNDO_GROUP:
			return new WP6UndoGroup(stream);

		case WP6_TOP_ATTRIBUTE_ON:
			return new WP6AttributeOnGroup(stream);

		case WP6_TOP_ATTRIBUTE_OFF:
			return new WP6AttributeOffGroup(stream);

		// Add the remaining cases here
		default:
			// should not happen
			return NULL;
	}
}

gboolean WP6FixedLengthGroup::_read(FILE *stream, guint size)
{
	guint32 startPosition = ftell(stream);
	WPD_CHECK_INTERNAL_ERROR(_readContents(stream));
	WPD_CHECK_FILE_SEEK_ERROR(fseek(stream, (startPosition + size - 1 - ftell(stream)), SEEK_CUR));
}
<|endoftext|>


<commit_before><commit_msg>[imageIO] Formatting `transposeImage`<commit_after><|endoftext|>


<commit_before>#include "primops.hh"
#include "eval-inline.hh"

#include "cpptoml/cpptoml.h"

namespace nix {

static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
    using namespace cpptoml;

    auto toml = state.forceStringNoCtx(*args[0], pos);

    std::istringstream tomlStream(toml);

    std::function<void(Value &, std::shared_ptr<base>)> visit;

    visit = [&](Value & v, std::shared_ptr<base> t) {

        if (auto t2 = t->as_table()) {

            size_t size = 0;
            for (auto & i : *t2) { (void) i; size++; }

            state.mkAttrs(v, size);

            for (auto & i : *t2) {
                auto & v2 = *state.allocAttr(v, state.symbols.create(i.first));

                if (auto i2 = i.second->as_table_array()) {
                    size_t size2 = i2->get().size();
                    state.mkList(v2, size2);
                    for (size_t j = 0; j < size2; ++j)
                        visit(*(v2.listElems()[j] = state.allocValue()), i2->get()[j]);
                }
                else
                    visit(v2, i.second);
            }

            v.attrs->sort();
        }

        else if (auto t2 = t->as_array()) {
            size_t size = t2->get().size();

            state.mkList(v, size);

            for (size_t i = 0; i < size; ++i)
                visit(*(v.listElems()[i] = state.allocValue()), t2->get()[i]);
        }

        else if (t->is_value()) {
            if (auto val = t->as<NixInt>())
                mkInt(v, val->get());
            else if (auto val = t->as<NixFloat>())
                mkFloat(v, val->get());
            else if (auto val = t->as<bool>())
                mkBool(v, val->get());
            else if (auto val = t->as<std::string>())
                mkString(v, val->get());
            else
                throw EvalError("unsupported value type in TOML");
        }

        else abort();
    };

    try {
        visit(v, parser(tomlStream).parse());
    } catch (std::runtime_error & e) {
        throw EvalError("while parsing a TOML string at %s: %s", pos, e.what());
    }
}

static RegisterPrimOp r("fromTOML", 1, prim_fromTOML);

}
<commit_msg>Fix build on 32-bit systems and macOS<commit_after>#include "primops.hh"
#include "eval-inline.hh"

#include "cpptoml/cpptoml.h"

namespace nix {

static void prim_fromTOML(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
    using namespace cpptoml;

    auto toml = state.forceStringNoCtx(*args[0], pos);

    std::istringstream tomlStream(toml);

    std::function<void(Value &, std::shared_ptr<base>)> visit;

    visit = [&](Value & v, std::shared_ptr<base> t) {

        if (auto t2 = t->as_table()) {

            size_t size = 0;
            for (auto & i : *t2) { (void) i; size++; }

            state.mkAttrs(v, size);

            for (auto & i : *t2) {
                auto & v2 = *state.allocAttr(v, state.symbols.create(i.first));

                if (auto i2 = i.second->as_table_array()) {
                    size_t size2 = i2->get().size();
                    state.mkList(v2, size2);
                    for (size_t j = 0; j < size2; ++j)
                        visit(*(v2.listElems()[j] = state.allocValue()), i2->get()[j]);
                }
                else
                    visit(v2, i.second);
            }

            v.attrs->sort();
        }

        else if (auto t2 = t->as_array()) {
            size_t size = t2->get().size();

            state.mkList(v, size);

            for (size_t i = 0; i < size; ++i)
                visit(*(v.listElems()[i] = state.allocValue()), t2->get()[i]);
        }

        else if (t->is_value()) {
            if (auto val = t->as<int64_t>())
                mkInt(v, val->get());
            else if (auto val = t->as<NixFloat>())
                mkFloat(v, val->get());
            else if (auto val = t->as<bool>())
                mkBool(v, val->get());
            else if (auto val = t->as<std::string>())
                mkString(v, val->get());
            else
                throw EvalError("unsupported value type in TOML");
        }

        else abort();
    };

    try {
        visit(v, parser(tomlStream).parse());
    } catch (std::runtime_error & e) {
        throw EvalError("while parsing a TOML string at %s: %s", pos, e.what());
    }
}

static RegisterPrimOp r("fromTOML", 1, prim_fromTOML);

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: query.hxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: hr $ $Date: 2001-11-01 16:17:44 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _DBA_COREAPI_QUERY_HXX_
#define _DBA_COREAPI_QUERY_HXX_

#ifndef _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
#include "querydescriptor.hxx"
#endif
#ifndef _DBA_CORE_CONFIGURATIONFLUSHABLE_HXX_
#include "configurationflushable.hxx"
#endif

#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif

#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef INCLUDED_MAP
#include <map>
#endif

//........................................................................
namespace dbaccess
{
//........................................................................

    class IWarningsContainer;
//==========================================================================
//= OQuery - an object implementing the sdb.Query service
//==========================================================================
typedef ::cppu::ImplHelper3 <   ::com::sun::star::sdbcx::XDataDescriptorFactory,
                                ::com::sun::star::beans::XPropertyChangeListener,
                                ::com::sun::star::sdbcx::XRename
                            >   OQuery_Base;
class OQuery;
class OColumn;
typedef ::comphelper::OPropertyArrayUsageHelper< OQuery >   OQuery_ArrayHelperBase;

class OQuery    :public OQueryDescriptor
                ,public OQuery_Base
                ,public OConfigurationFlushable
                ,public OQuery_ArrayHelperBase
{
    friend struct TRelease;

public:
    typedef ::std::map< ::rtl::OUString,OColumn*,::comphelper::UStringMixLess> TNameColumnMap;

protected:
//  TNameColumnMap      m_aColumnMap; // contains all columnnames to columns
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                        m_xCommandDefinition;
    ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                        m_xConnection;
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > m_xCommandPropInfo;
    IWarningsContainer* m_pWarnings;
    sal_Bool            m_bCaseSensitiv : 1;        // assume case sensitivity of the column names ?

    // possible actions on our "aggregate"
    enum AGGREGATE_ACTION { NONE, SETTING_PROPERTIES, FLUSHING };
    AGGREGATE_ACTION    m_eDoingCurrently;

    // ------------------------------------------------------------------------
    /** a class which automatically resets m_eDoingCurrently in it's destructor
    */
    class OAutoActionReset; // just for the following friend declaration
    friend class OAutoActionReset;
    class OAutoActionReset
    {
        OQuery*             m_pActor;
    public:
        OAutoActionReset(OQuery* _pActor) : m_pActor(_pActor) { }
        ~OAutoActionReset() { m_pActor->m_eDoingCurrently = NONE; }
    };

protected:
    ~OQuery();

public:
    OQuery(
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxCommandDefinition,
            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConn
        );

// ::com::sun::star::uno::XInterface
    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL acquire(  ) throw();
    virtual void SAL_CALL release(  ) throw();

protected:
// OPropertyArrayUsageHelper
    virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
    ::cppu::IPropertyArrayHelper*   getArrayHelper() { return OQuery_ArrayHelperBase::getArrayHelper(); }

// ::com::sun::star::uno::XTypeProvider
    virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);

// OPropertySetHelper
    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

// ::com::sun::star::lang::XServiceInfo
    DECLARE_SERVICE_INFO();

// ::com::sun::star::sdbcx::XDataDescriptorFactory
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor(  ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertyChangeListener
    virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XEventListener
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException);

// OPropertySetHelper
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
                    sal_Int32 nHandle,
                    const ::com::sun::star::uno::Any& rValue )
            throw (::com::sun::star::uno::Exception);

public:
    // the caller is responsible for the lifetime!
    void                setWarningsContainer( IWarningsContainer* _pWarnings )  { m_pWarnings = _pWarnings; }
    IWarningsContainer* getWarningsContainer( ) const                           { return m_pWarnings; }

public:
// helper

// pseudo-XComponent
    virtual void SAL_CALL dispose();

// OQueryDescriptor
    void    storeTo( const ::utl::OConfigurationNode& _rConfigLocation );
    void    loadFrom( const ::utl::OConfigurationNode& _rConfigLocation );

    // XRename
    virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

protected:
// OConfigurationFlushable
    virtual void flush_NoBroadcast_NoCommit();
    virtual OColumn* createColumn(const ::rtl::OUString& _rName) const;

    virtual ::utl::OConfigurationNode getObjectLocation() const;

    virtual void rebuildColumns( );

private:
    /** creates column objects for all columns which are necessary when executing our command
    @param _bOnlyTemporary
        if <TRUE/>, the resulting columns are inserted into m_aColumnMap only, else they're really appended to m_pColumns
    */
    void implCollectColumns( );
};

//........................................................................
}   // namespace dbaccess
//........................................................................

#endif // _DBA_COREAPI_QUERY_HXX_

<commit_msg>INTEGRATION: CWS insight01 (1.14.124); FILE MERGED 2003/12/17 09:18:58 oj 1.14.124.3: #111075# ongoing work 2003/11/17 09:39:05 oj 1.14.124.2: #111075# ongoning work 2003/10/24 06:30:00 oj 1.14.124.1: #i21643# import filter changes<commit_after>/*************************************************************************
 *
 *  $RCSfile: query.hxx,v $
 *
 *  $Revision: 1.15 $
 *
 *  last change: $Author: hr $ $Date: 2004-08-02 15:03:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _DBA_COREAPI_QUERY_HXX_
#define _DBA_COREAPI_QUERY_HXX_

#ifndef _DBA_COREAPI_QUERYDESCRIPTOR_HXX_
#include "querydescriptor.hxx"
#endif
#ifndef _CPPUHELPER_IMPLBASE3_HXX_
#include <cppuhelper/implbase3.hxx>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XDATADESCRIPTORFACTORY_HPP_
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_BEANS_XPROPERTYCHANGELISTENER_HPP_
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_
#include <com/sun/star/sdbc/XConnection.hpp>
#endif
#ifndef _COM_SUN_STAR_SDBCX_XRENAME_HPP_
#include <com/sun/star/sdbcx/XRename.hpp>
#endif
#ifndef DBA_CONTENTHELPER_HXX
#include "ContentHelper.hxx"
#endif

#include <map>

//........................................................................
namespace dbaccess
{
//........................................................................

    class IWarningsContainer;
//==========================================================================
//= OQuery - an object implementing the sdb.Query service
//==========================================================================
typedef ::cppu::ImplHelper3 <   ::com::sun::star::sdbcx::XDataDescriptorFactory,
                                ::com::sun::star::beans::XPropertyChangeListener,
                                ::com::sun::star::sdbcx::XRename
                            >   OQuery_Base;
class OQuery;
class OColumn;
typedef ::comphelper::OPropertyArrayUsageHelper< OQuery >   OQuery_ArrayHelperBase;

class OQuery    :public OContentHelper
                ,public OQueryDescriptor_Base
                ,public OQuery_Base
                ,public OQuery_ArrayHelperBase
                ,public ODataSettings
{
    friend struct TRelease;

public:
    typedef ::std::map< ::rtl::OUString,OColumn*,::comphelper::UStringMixLess> TNameColumnMap;

protected:
//  TNameColumnMap      m_aColumnMap; // contains all columnnames to columns
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                        m_xCommandDefinition;
    ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >
                        m_xConnection;
    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > m_xCommandPropInfo;
    ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener > m_xColumnMediator;
    OContainerMediator* m_pMediator;
    IWarningsContainer* m_pWarnings;
    sal_Bool            m_bCaseSensitiv : 1;        // assume case sensitivity of the column names ?

    // possible actions on our "aggregate"
    enum AGGREGATE_ACTION { NONE, SETTING_PROPERTIES, FLUSHING };
    AGGREGATE_ACTION    m_eDoingCurrently;

    // ------------------------------------------------------------------------
    /** a class which automatically resets m_eDoingCurrently in it's destructor
    */
    class OAutoActionReset; // just for the following friend declaration
    friend class OAutoActionReset;
    class OAutoActionReset
    {
        OQuery*             m_pActor;
    public:
        OAutoActionReset(OQuery* _pActor) : m_pActor(_pActor) { }
        ~OAutoActionReset() { m_pActor->m_eDoingCurrently = NONE; }
    };

protected:
    virtual ~OQuery();

// OPropertyArrayUsageHelper
    virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
    ::cppu::IPropertyArrayHelper*   getArrayHelper() { return OQuery_ArrayHelperBase::getArrayHelper(); }

public:
    OQuery(
            const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _rxCommandDefinition,
            const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConn,
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xORB
        );

// com::sun::star::lang::XTypeProvider
    DECLARE_TYPEPROVIDER( );

// ::com::sun::star::uno::XInterface
    DECLARE_XINTERFACE( )

// ::com::sun::star::beans::XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);

// OPropertySetHelper
    virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

// ::com::sun::star::lang::XServiceInfo
    DECLARE_SERVICE_INFO();

// ::com::sun::star::sdbcx::XDataDescriptorFactory
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > SAL_CALL createDataDescriptor(  ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::beans::XPropertyChangeListener
    virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException);

// ::com::sun::star::lang::XEventListener
        virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& _rSource ) throw (::com::sun::star::uno::RuntimeException);

// OPropertySetHelper
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast(
                    sal_Int32 nHandle,
                    const ::com::sun::star::uno::Any& rValue )
            throw (::com::sun::star::uno::Exception);

public:
    // the caller is responsible for the lifetime!
    void                setWarningsContainer( IWarningsContainer* _pWarnings )  { m_pWarnings = _pWarnings; }
    IWarningsContainer* getWarningsContainer( ) const                           { return m_pWarnings; }

    // XRename
    virtual void SAL_CALL rename( const ::rtl::OUString& newName ) throw (::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);

protected:
    virtual void SAL_CALL disposing();

    virtual OColumn* createColumn(const ::rtl::OUString& _rName) const;

    virtual void rebuildColumns( );

private:
    /** creates column objects for all columns which are necessary when executing our command
    @param _bOnlyTemporary
        if <TRUE/>, the resulting columns are inserted into m_aColumnMap only, else they're really appended to m_pColumns
    */
    void implCollectColumns( );

    void registerProperties();
};

//........................................................................
}   // namespace dbaccess
//........................................................................

#endif // _DBA_COREAPI_QUERY_HXX_

<|endoftext|>


<commit_before>// Copyright (c) 2007, 2008 libmv authors.
//
// 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.

#include <cassert>
#include <vector>

#include "libmv/numeric/numeric.h"
#include "libmv/correspondence/klt.h"
#include "libmv/image/image.h"
#include "libmv/image/image_io.h"
#include "libmv/image/convolve.h"
#include "libmv/image/sample.h"

using std::vector;

namespace libmv {

static void FindLocalMaxima(const FloatImage &trackness,
                            float min_trackness,
                            KLTContext::FeatureList *features) {
  for (int i = 1; i < trackness.Height()-1; ++i) {
    for (int j = 1; j < trackness.Width()-1; ++j) {
      if (   trackness(i,j) >= min_trackness
          && trackness(i,j) >= trackness(i-1, j-1)
          && trackness(i,j) >= trackness(i-1, j  )
          && trackness(i,j) >= trackness(i-1, j+1)
          && trackness(i,j) >= trackness(i  , j-1)
          && trackness(i,j) >= trackness(i  , j+1)
          && trackness(i,j) >= trackness(i+1, j-1)
          && trackness(i,j) >= trackness(i+1, j  )
          && trackness(i,j) >= trackness(i+1, j+1)) {
        KLTPointFeature *p = new KLTPointFeature;
        p->position(1) = i;
        p->position(0) = j;
        p->trackness = trackness(i,j);
        features->push_back(p);
      }
    }
  }
}

// Compute the gradient matrix noted by Z in Good Features to Track.
//
//   Z = [gxx gxy; gxy gyy]
//
// This function computes the matrix for every pixel.
static void ComputeGradientMatrix(const Array3Df &image_and_gradients,
                                       int window_size,
                                       Array3Df *gradient_matrix) {
  Array3Df gradients;
  gradients.ResizeLike(image_and_gradients);
  for (int j = 0; j < image_and_gradients.Height(); ++j) {
    for (int i = 0; i < image_and_gradients.Width(); ++i) {
      float gx = image_and_gradients(j, i, 1);
      float gy = image_and_gradients(j, i, 2);
      gradients(j, i, 0) = gx * gx;
      gradients(j, i, 1) = gx * gy;
      gradients(j, i, 2) = gy * gy;
    }
  }
  // Sum the gradient matrix over tracking window for each pixel.
  BoxFilter(gradients, window_size, gradient_matrix);
}

// Given the three distinct elements of the symmetric 2x2 matrix
//
//                     [gxx gxy]
//                     [gxy gyy],
//
// return the minimum eigenvalue of the matrix.
// Borrowed from Stan Birchfield's KLT implementation.
static float MinEigenValue(float gxx, float gxy, float gyy) {
  return (gxx + gyy - sqrt((gxx - gyy) * (gxx - gyy) + 4 * gxy * gxy)) / 2.0f;
}

// Compute trackness of every pixel given the gradient matrix.
// This is done as described in the Good Features to Track paper.
static void ComputeTrackness(const Array3Df gradient_matrix,
                             Array3Df *trackness_pointer,
                             double *trackness_mean) {
  Array3Df &trackness = *trackness_pointer;
  trackness.Resize(gradient_matrix.Height(), gradient_matrix.Width());
  *trackness_mean = 0;
  for (int i = 0; i < trackness.Height(); ++i) {
    for (int j = 0; j < trackness.Width(); ++j) {
      double t = MinEigenValue(gradient_matrix(i, j, 0),
                               gradient_matrix(i, j, 1),
                               gradient_matrix(i, j, 2));
      trackness(i, j) = t;
      *trackness_mean += t;
    }
  }
  *trackness_mean /= trackness.Size();
}

static double dist2(const Vec2f &x, const Vec2f &y) {
  double a = x(0) - y(0);
  double b = x(1) - y(1);
  return a * a + b * b;
}

// TODO(keir): Use Stan's neat trick of using a 'punch-out' array to detect
// too-closes features. This is O(n^2)!
static void RemoveTooCloseFeatures(KLTContext::FeatureList *features,
                                   double mindist2) {

  KLTContext::FeatureList::iterator i = features->begin();
  while (i != features->end()) {
    bool i_deleted = false;
    KLTContext::FeatureList::iterator j = i;
    ++j;
    while (j != features->end() && !i_deleted) {
      if (dist2((*i)->position, (*j)->position) < mindist2) {
        KLTContext::FeatureList::iterator to_delete;
        if ((*i)->trackness < (*j)->trackness) {
          to_delete = i;
          ++i;
          i_deleted = true;
        } else {
          to_delete = j;
          ++j;
        }
        delete *to_delete;
        features->erase(to_delete);
      } else {
        ++j;
      }
    }
    if (!i_deleted) {
      ++i;
    }
  }
}

void KLTContext::DetectGoodFeatures(const Array3Df &image_and_gradients,
                                    FeatureList *features) {
  Array3Df gradient_matrix;
  ComputeGradientMatrix(image_and_gradients, WindowSize(), &gradient_matrix);

  Array3Df trackness;
  double trackness_mean;
  ComputeTrackness(gradient_matrix, &trackness, &trackness_mean);
  min_trackness_ = trackness_mean;

  FindLocalMaxima(trackness, min_trackness_, features);

  RemoveTooCloseFeatures(features, min_feature_dist_ * min_feature_dist_);
}

// TODO(keir): Restore or delete these functions...
void KLTContext::TrackFeatures(ImagePyramid *pyramid1,
                               const FeatureList &features1,
                               ImagePyramid *pyramid2,
                               FeatureList *features2_pointer) {
  FeatureList &features2 = *features2_pointer;

  features2.clear();
  for (FeatureList::const_iterator i = features1.begin();
       i != features1.end(); ++i) {
    KLTPointFeature *tracked_feature = new KLTPointFeature;
    TrackFeature(pyramid1, **i, pyramid2, tracked_feature);
    features2.push_back(tracked_feature);
  }
}

void KLTContext::TrackFeature(ImagePyramid *pyramid1,
                              const KLTPointFeature &feature1,
                              ImagePyramid *pyramid2,
                              KLTPointFeature *feature2_pointer) {
  const int highest_level = pyramid1->NumLevels() - 1;

  Vec2 position1, position2;
  position2(0) = feature1.position(0) / pow(2., highest_level + 1);
  position2(1) = feature1.position(1) / pow(2., highest_level + 1);

  for (int i = highest_level; i >= 0; --i) {
    position1(0) = feature1.position(0) / pow(2., i);
    position1(1) = feature1.position(1) / pow(2., i);
    position2(0) *= 2;
    position2(1) *= 2;

    TrackFeatureOneLevel(pyramid1->Level(i),
                         position1,
                         pyramid2->Level(i),
                         &position2);
  }
  feature2_pointer->position = position2;
}

// Compute the gradient matrix noted by Z and the error vector e.
// See Good Features to Track.
static void ComputeTrackingEquation(const Array3Df &image_and_gradient1,
                                    const Array3Df &image_and_gradient2,
                                    const Vec2 &position1,
                                    const Vec2 &position2,
                                    int half_width,
                                    float *gxx,
                                    float *gxy,
                                    float *gyy,
                                    float *ex,
                                    float *ey) {
  *gxx = 0;
  *gxy = 0;
  *gyy = 0;
  *ex = 0;
  *ey = 0;
  for (int i = -half_width; i <= half_width; ++i) {
    for (int j = -half_width; j <= half_width; ++j) {
      float x1 = position1(0) + j;
      float y1 = position1(1) + i;
      float x2 = position2(0) + j;
      float y2 = position2(1) + i;
      // TODO(pau): should do boundary checking outside this loop, and call here
      // a sampler that does not boundary checking.
      float I = SampleLinear(image_and_gradient1, y1, x1, 0);
      float J = SampleLinear(image_and_gradient2, y2, x2, 0);
      float gx = SampleLinear(image_and_gradient2, y2, x2, 1);
      float gy = SampleLinear(image_and_gradient2, y2, x2, 2);
      *gxx += gx * gx;
      *gxy += gx * gy;
      *gyy += gy * gy;
      *ex += (I - J) * gx;
      *ey += (I - J) * gy;
    }
  }
}

// Solve the tracking equation
//
//   [gxx gxy] [dx] = [ex]
//   [gxy gyy] [dy] = [ey]
//
// for dx and dy.  Borrowed from Stan Birchfield's KLT implementation.
static bool SolveTrackingEquation(float gxx, float gxy, float gyy,
                                  float ex, float ey,
                                  float min_determinant,
                                  float *dx, float *dy) {
  float det = gxx * gyy - gxy * gxy;
//  printf("det=%f, min_det=%f, gxx=%f, gxy=%f, gyy=%f\n", det, min_determinant,
//      gxx, gxy, gyy);
  if (det < min_determinant) {
    *dx = 0;
    *dy = 0;
    return false;
  }
  *dx = (gyy * ex - gxy * ey) / det;
  *dy = (gxx * ey - gxy * ex) / det;
  return true;
}

void KLTContext::TrackFeatureOneLevel(const Array3Df &image_and_gradient1,
                                      const Vec2 &position1,
                                      const Array3Df &image_and_gradient2,
                                      Vec2 *position2_pointer) {
  Vec2 &position2 = *position2_pointer;

  for (int i = 0; i < max_iterations_; ++i) {
    // Compute gradient matrix and error vector.
    float gxx, gxy, gyy, ex, ey;
    ComputeTrackingEquation(image_and_gradient1, image_and_gradient2,
                            position1, position2,
                            HalfWindowSize(),
                            &gxx, &gxy, &gyy, &ex, &ey);
    // Solve the linear system for deltad.
    float dx, dy;
    if (!SolveTrackingEquation(gxx, gxy, gyy, ex, ey, min_determinant_,
                               &dx, &dy)) {
      // TODO(keir): drop feature.
//      printf("dropped!\n");
    }

    // Update feature2 position.
    position2(0) += dx;
    position2(1) += dy;

    // TODO(keir): Handle other tracking failure conditions and pass the
    // reasons out to the caller. For example, for pyramid tracking a failure
    // at a coarse level suggests trying again at a finer level.
    if (Square(dx) + Square(dy) < min_update_distance2_) {
//      printf("distance too small: %f, %f\n", dx, dy);
      break;
    }
//    printf("dx=%f, dy=%f\n", dx, dy);
  }
}

void KLTContext::DrawFeatureList(const FeatureList &features,
                                 const Vec3 &color,
                                 FloatImage *image) const {
  for (FeatureList::const_iterator i = features.begin();
       i != features.end(); ++i) {
    DrawFeature(**i, color, image);
  }
}

void KLTContext::DrawFeature(const KLTPointFeature &feature,
                             const Vec3 &color,
                             FloatImage *image) const {
  assert(image->Depth() == 3);

  const int cross_width = 5;
  int x = lround(feature.position(0));
  int y = lround(feature.position(1));
  if (!image->Contains(y,x)) {
    return;
  }

  // Draw vertical line.
  for (int i = max(0, y - cross_width);
       i < min(image->Height(), y + cross_width + 1); ++i) {
    for (int k = 0; k < 3; ++k) {
      (*image)(i, x, k) = color(k);
    }
  }
  // Draw horizontal line.
  for (int j = max(0, x - cross_width);
       j < min(image->Width(), x + cross_width + 1); ++j) {
    for (int k = 0; k < 3; ++k) {
      (*image)(y, j, k) = color(k);
    }
  }
}

}  // namespace libmv
<commit_msg>Add debug printing to KLT.<commit_after>// Copyright (c) 2007, 2008 libmv authors.
//
// 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.

#include <cassert>
#include <vector>

#include "libmv/numeric/numeric.h"
#include "libmv/correspondence/klt.h"
#include "libmv/image/image.h"
#include "libmv/image/image_io.h"
#include "libmv/image/convolve.h"
#include "libmv/image/sample.h"

using std::vector;

namespace libmv {

static void FindLocalMaxima(const FloatImage &trackness,
                            float min_trackness,
                            KLTContext::FeatureList *features) {
  for (int i = 1; i < trackness.Height()-1; ++i) {
    for (int j = 1; j < trackness.Width()-1; ++j) {
      if (   trackness(i,j) >= min_trackness
          && trackness(i,j) >= trackness(i-1, j-1)
          && trackness(i,j) >= trackness(i-1, j  )
          && trackness(i,j) >= trackness(i-1, j+1)
          && trackness(i,j) >= trackness(i  , j-1)
          && trackness(i,j) >= trackness(i  , j+1)
          && trackness(i,j) >= trackness(i+1, j-1)
          && trackness(i,j) >= trackness(i+1, j  )
          && trackness(i,j) >= trackness(i+1, j+1)) {
        KLTPointFeature *p = new KLTPointFeature;
        p->position(1) = i;
        p->position(0) = j;
        p->trackness = trackness(i,j);
        features->push_back(p);
      }
    }
  }
}

// Compute the gradient matrix noted by Z in Good Features to Track.
//
//   Z = [gxx gxy; gxy gyy]
//
// This function computes the matrix for every pixel.
static void ComputeGradientMatrix(const Array3Df &image_and_gradients,
                                       int window_size,
                                       Array3Df *gradient_matrix) {
  Array3Df gradients;
  gradients.ResizeLike(image_and_gradients);
  for (int j = 0; j < image_and_gradients.Height(); ++j) {
    for (int i = 0; i < image_and_gradients.Width(); ++i) {
      float gx = image_and_gradients(j, i, 1);
      float gy = image_and_gradients(j, i, 2);
      gradients(j, i, 0) = gx * gx;
      gradients(j, i, 1) = gx * gy;
      gradients(j, i, 2) = gy * gy;
    }
  }
  // Sum the gradient matrix over tracking window for each pixel.
  BoxFilter(gradients, window_size, gradient_matrix);
}

// Given the three distinct elements of the symmetric 2x2 matrix
//
//                     [gxx gxy]
//                     [gxy gyy],
//
// return the minimum eigenvalue of the matrix.
// Borrowed from Stan Birchfield's KLT implementation.
static float MinEigenValue(float gxx, float gxy, float gyy) {
  return (gxx + gyy - sqrt((gxx - gyy) * (gxx - gyy) + 4 * gxy * gxy)) / 2.0f;
}

// Compute trackness of every pixel given the gradient matrix.
// This is done as described in the Good Features to Track paper.
static void ComputeTrackness(const Array3Df gradient_matrix,
                             Array3Df *trackness_pointer,
                             double *trackness_mean) {
  Array3Df &trackness = *trackness_pointer;
  trackness.Resize(gradient_matrix.Height(), gradient_matrix.Width());
  *trackness_mean = 0;
  for (int i = 0; i < trackness.Height(); ++i) {
    for (int j = 0; j < trackness.Width(); ++j) {
      double t = MinEigenValue(gradient_matrix(i, j, 0),
                               gradient_matrix(i, j, 1),
                               gradient_matrix(i, j, 2));
      trackness(i, j) = t;
      *trackness_mean += t;
    }
  }
  *trackness_mean /= trackness.Size();
}

static double dist2(const Vec2f &x, const Vec2f &y) {
  double a = x(0) - y(0);
  double b = x(1) - y(1);
  return a * a + b * b;
}

// TODO(keir): Use Stan's neat trick of using a 'punch-out' array to detect
// too-closes features. This is O(n^2)!
static void RemoveTooCloseFeatures(KLTContext::FeatureList *features,
                                   double mindist2) {

  KLTContext::FeatureList::iterator i = features->begin();
  while (i != features->end()) {
    bool i_deleted = false;
    KLTContext::FeatureList::iterator j = i;
    ++j;
    while (j != features->end() && !i_deleted) {
      if (dist2((*i)->position, (*j)->position) < mindist2) {
        KLTContext::FeatureList::iterator to_delete;
        if ((*i)->trackness < (*j)->trackness) {
          to_delete = i;
          ++i;
          i_deleted = true;
        } else {
          to_delete = j;
          ++j;
        }
        delete *to_delete;
        features->erase(to_delete);
      } else {
        ++j;
      }
    }
    if (!i_deleted) {
      ++i;
    }
  }
}

void KLTContext::DetectGoodFeatures(const Array3Df &image_and_gradients,
                                    FeatureList *features) {
  Array3Df gradient_matrix;
  ComputeGradientMatrix(image_and_gradients, WindowSize(), &gradient_matrix);

  Array3Df trackness;
  double trackness_mean;
  ComputeTrackness(gradient_matrix, &trackness, &trackness_mean);
  min_trackness_ = trackness_mean;

  FindLocalMaxima(trackness, min_trackness_, features);

  RemoveTooCloseFeatures(features, min_feature_dist_ * min_feature_dist_);
}

// TODO(keir): Restore or delete these functions...
void KLTContext::TrackFeatures(ImagePyramid *pyramid1,
                               const FeatureList &features1,
                               ImagePyramid *pyramid2,
                               FeatureList *features2_pointer) {
  FeatureList &features2 = *features2_pointer;

  features2.clear();
  for (FeatureList::const_iterator i = features1.begin();
       i != features1.end(); ++i) {
    KLTPointFeature *tracked_feature = new KLTPointFeature;
    TrackFeature(pyramid1, **i, pyramid2, tracked_feature);
    features2.push_back(tracked_feature);
  }
}

void KLTContext::TrackFeature(ImagePyramid *pyramid1,
                              const KLTPointFeature &feature1,
                              ImagePyramid *pyramid2,
                              KLTPointFeature *feature2_pointer) {
  const int highest_level = pyramid1->NumLevels() - 1;

  Vec2 position1, position2;
  position2(0) = feature1.position(0) / pow(2., highest_level + 1);
  position2(1) = feature1.position(1) / pow(2., highest_level + 1);

  for (int i = highest_level; i >= 0; --i) {
    position1(0) = feature1.position(0) / pow(2., i);
    position1(1) = feature1.position(1) / pow(2., i);
    position2(0) *= 2;
    position2(1) *= 2;

    TrackFeatureOneLevel(pyramid1->Level(i),
                         position1,
                         pyramid2->Level(i),
                         &position2);
  }
  feature2_pointer->position = position2;
}

// Compute the gradient matrix noted by Z and the error vector e.
// See Good Features to Track.
static void ComputeTrackingEquation(const Array3Df &image_and_gradient1,
                                    const Array3Df &image_and_gradient2,
                                    const Vec2 &position1,
                                    const Vec2 &position2,
                                    int half_width,
                                    float *gxx,
                                    float *gxy,
                                    float *gyy,
                                    float *ex,
                                    float *ey) {
  *gxx = 0;
  *gxy = 0;
  *gyy = 0;
  *ex = 0;
  *ey = 0;
  for (int i = -half_width; i <= half_width; ++i) {
    for (int j = -half_width; j <= half_width; ++j) {
      float x1 = position1(0) + j;
      float y1 = position1(1) + i;
      float x2 = position2(0) + j;
      float y2 = position2(1) + i;
      // TODO(pau): should do boundary checking outside this loop, and call here
      // a sampler that does not boundary checking.
      float I = SampleLinear(image_and_gradient1, y1, x1, 0);
      float J = SampleLinear(image_and_gradient2, y2, x2, 0);
      float gx = SampleLinear(image_and_gradient2, y2, x2, 1);
      float gy = SampleLinear(image_and_gradient2, y2, x2, 2);
      *gxx += gx * gx;
      *gxy += gx * gy;
      *gyy += gy * gy;
      *ex += (I - J) * gx;
      *ey += (I - J) * gy;
    }
  }
}

// Solve the tracking equation
//
//   [gxx gxy] [dx] = [ex]
//   [gxy gyy] [dy] = [ey]
//
// for dx and dy.  Borrowed from Stan Birchfield's KLT implementation.
static bool SolveTrackingEquation(float gxx, float gxy, float gyy,
                                  float ex, float ey,
                                  float min_determinant,
                                  float *dx, float *dy) {
  float det = gxx * gyy - gxy * gxy;
//  printf("det=%f, min_det=%f, gxx=%f, gxy=%f, gyy=%f\n", det, min_determinant,
//      gxx, gxy, gyy);
  if (det < min_determinant) {
    *dx = 0;
    *dy = 0;
    return false;
  }
  *dx = (gyy * ex - gxy * ey) / det;
  *dy = (gxx * ey - gxy * ex) / det;
  return true;
}

void KLTContext::TrackFeatureOneLevel(const Array3Df &image_and_gradient1,
                                      const Vec2 &position1,
                                      const Array3Df &image_and_gradient2,
                                      Vec2 *position2_pointer) {
  Vec2 &position2 = *position2_pointer;

  int i;
  float dx=0, dy=0;
  max_iterations_ = 30;
  printf("disps = array([\n");
  for (i = 0; i < max_iterations_; ++i) {
    // Compute gradient matrix and error vector.
    float gxx, gxy, gyy, ex, ey;
    ComputeTrackingEquation(image_and_gradient1, image_and_gradient2,
                            position1, position2,
                            HalfWindowSize(),
                            &gxx, &gxy, &gyy, &ex, &ey);
    // Solve the linear system for deltad.
    if (!SolveTrackingEquation(gxx, gxy, gyy, ex, ey, min_determinant_,
                               &dx, &dy)) {
      // TODO(keir): drop feature.
      printf("dropped!\n");
    }

    // shrink the update
    dx *= 0.5;
    dy *= 0.5;

    // Update feature2 position.
    position2(0) += dx;
    position2(1) += dy;

    printf("  [%10f, %10f, %10f, %10f],\n", dx, dy, position2(0), position2(1));

    // TODO(keir): Handle other tracking failure conditions and pass the
    // reasons out to the caller. For example, for pyramid tracking a failure
    // at a coarse level suggests trying again at a finer level.
    if (Square(dx) + Square(dy) < min_update_distance2_) {
      printf("# distance too small: %f, %f\n", dx, dy);
      break;
    }
//    printf("dx=%f, dy=%f\n", dx, dy);
  }
  printf("])\n");
  if (i == max_iterations_) {
    printf("hit max iters. dx=%f, dy=%f\n", dx, dy);
  }
}

void KLTContext::DrawFeatureList(const FeatureList &features,
                                 const Vec3 &color,
                                 FloatImage *image) const {
  for (FeatureList::const_iterator i = features.begin();
       i != features.end(); ++i) {
    DrawFeature(**i, color, image);
  }
}

void KLTContext::DrawFeature(const KLTPointFeature &feature,
                             const Vec3 &color,
                             FloatImage *image) const {
  assert(image->Depth() == 3);

  const int cross_width = 5;
  int x = lround(feature.position(0));
  int y = lround(feature.position(1));
  if (!image->Contains(y,x)) {
    return;
  }

  // Draw vertical line.
  for (int i = max(0, y - cross_width);
       i < min(image->Height(), y + cross_width + 1); ++i) {
    for (int k = 0; k < 3; ++k) {
      (*image)(i, x, k) = color(k);
    }
  }
  // Draw horizontal line.
  for (int j = max(0, x - cross_width);
       j < min(image->Width(), x + cross_width + 1); ++j) {
    for (int k = 0; k < 3; ++k) {
      (*image)(y, j, k) = color(k);
    }
  }
}

}  // namespace libmv
<|endoftext|>