<commit_before>/*
 * Copyright 2011, Blender Foundation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "device.h"
#include "particles.h"
#include "scene.h"

#include "util_foreach.h"
#include "util_map.h"
#include "util_progress.h"
#include "util_vector.h"

CCL_NAMESPACE_BEGIN

/* Particle System */

ParticleSystem::ParticleSystem()
{
}

ParticleSystem::~ParticleSystem()
{
}

void ParticleSystem::tag_update(Scene *scene)
{
	scene->particle_system_manager->need_update = true;
}

/* Particle System Manager */

ParticleSystemManager::ParticleSystemManager()
{
	need_update = true;
}

ParticleSystemManager::~ParticleSystemManager()
{
}

void ParticleSystemManager::device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
	/* count particles.
	 * adds one dummy particle at the beginning to avoid invalid lookups,
	 * in case a shader uses particle info without actual particle data.
	 */
	int num_particles = 1;
	foreach(ParticleSystem *psys, scene->particle_systems)
		num_particles += psys->particles.size();

	float4 *particles = dscene->particles.resize(PARTICLE_SIZE*num_particles);

	/* dummy particle */
	particles[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);

	int i = 1;
	foreach(ParticleSystem *psys, scene->particle_systems) {
		foreach(Particle &pa, psys->particles) {
			/* pack in texture */
			int offset = i*PARTICLE_SIZE;

			particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size);
			particles[offset+1] = pa.rotation;
			particles[offset+2] = make_float4(pa.location.x, pa.location.y, pa.location.z, pa.velocity.x);
			particles[offset+3] = make_float4(pa.velocity.y, pa.velocity.z, pa.angular_velocity.x, pa.angular_velocity.y);
			particles[offset+4] = make_float4(pa.angular_velocity.z, 0.0f, 0.0f, 0.0f);

			i++;

			if(progress.get_cancel()) return;
		}
	}

	device->tex_alloc("__particles", dscene->particles);
}

void ParticleSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
	if(!need_update)
		return;

	device_free(device, dscene);

	if(scene->particle_systems.size() == 0)
		return;

	progress.set_status("Updating Particle Systems", "Copying Particles to device");
	device_update_particles(device, dscene, scene, progress);

	if(progress.get_cancel()) return;

	need_update = false;
}

void ParticleSystemManager::device_free(Device *device, DeviceScene *dscene)
{
	device->tex_free(dscene->particles);
	dscene->particles.clear();
}

void ParticleSystemManager::tag_update(Scene *scene)
{
	need_update = true;
}

CCL_NAMESPACE_END

<commit_msg>Cycles: Fully initialize the dummy particle at index 0.<commit_after>/*
 * Copyright 2011, Blender Foundation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "device.h"
#include "particles.h"
#include "scene.h"

#include "util_foreach.h"
#include "util_map.h"
#include "util_progress.h"
#include "util_vector.h"

CCL_NAMESPACE_BEGIN

/* Particle System */

ParticleSystem::ParticleSystem()
{
}

ParticleSystem::~ParticleSystem()
{
}

void ParticleSystem::tag_update(Scene *scene)
{
	scene->particle_system_manager->need_update = true;
}

/* Particle System Manager */

ParticleSystemManager::ParticleSystemManager()
{
	need_update = true;
}

ParticleSystemManager::~ParticleSystemManager()
{
}

void ParticleSystemManager::device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
	/* count particles.
	 * adds one dummy particle at the beginning to avoid invalid lookups,
	 * in case a shader uses particle info without actual particle data.
	 */
	int num_particles = 1;
	foreach(ParticleSystem *psys, scene->particle_systems)
		num_particles += psys->particles.size();

	float4 *particles = dscene->particles.resize(PARTICLE_SIZE*num_particles);

	/* dummy particle */
	particles[0] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
	particles[1] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
	particles[2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
	particles[3] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
	particles[4] = make_float4(0.0f, 0.0f, 0.0f, 0.0f);

	int i = 1;
	foreach(ParticleSystem *psys, scene->particle_systems) {
		foreach(Particle &pa, psys->particles) {
			/* pack in texture */
			int offset = i*PARTICLE_SIZE;

			particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size);
			particles[offset+1] = pa.rotation;
			particles[offset+2] = make_float4(pa.location.x, pa.location.y, pa.location.z, pa.velocity.x);
			particles[offset+3] = make_float4(pa.velocity.y, pa.velocity.z, pa.angular_velocity.x, pa.angular_velocity.y);
			particles[offset+4] = make_float4(pa.angular_velocity.z, 0.0f, 0.0f, 0.0f);

			i++;

			if(progress.get_cancel()) return;
		}
	}

	device->tex_alloc("__particles", dscene->particles);
}

void ParticleSystemManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
	if(!need_update)
		return;

	device_free(device, dscene);

	if(scene->particle_systems.size() == 0)
		return;

	progress.set_status("Updating Particle Systems", "Copying Particles to device");
	device_update_particles(device, dscene, scene, progress);

	if(progress.get_cancel()) return;

	need_update = false;
}

void ParticleSystemManager::device_free(Device *device, DeviceScene *dscene)
{
	device->tex_free(dscene->particles);
	dscene->particles.clear();
}

void ParticleSystemManager::tag_update(Scene *scene)
{
	need_update = true;
}

CCL_NAMESPACE_END

<|endoftext|>


<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptMethodSteepestDescent.cpp,v $
   $Revision: 1.13 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/10/22 13:36:25 $
   End CVS Header */

#include "copasi.h"

#include "COptMethod.h"
#include "COptProblem.h"
#include "COptItem.h"
#include "COptTask.h"

#include "FminBrent.h"

#include "report/CCopasiObjectReference.h"

COptMethodSteepestDescent::COptMethodSteepestDescent(const CCopasiContainer * pParent):
    COptMethod(CCopasiTask::optimization, CCopasiMethod::SteepestDescent, pParent),
    mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine))
{
  addParameter("Iteration Limit", CCopasiParameter::UINT, (unsigned C_INT32) 100);
  addParameter("Tolerance", CCopasiParameter::DOUBLE, (C_FLOAT64) 1e-6);
}

COptMethodSteepestDescent::COptMethodSteepestDescent(const COptMethodSteepestDescent & src,
    const CCopasiContainer * pParent): COptMethod(src, pParent),
    mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine))
{}

COptMethodSteepestDescent::~COptMethodSteepestDescent()
{
  pdelete(mpDescent);

  cleanup();
}

bool COptMethodSteepestDescent::optimise()
{
  if (!initialize()) return false;

  unsigned C_INT32 i, k;
  C_FLOAT64 tmp, x0, alpha, mn, mx, fmn, fmx;
  bool calc_grad;

  // initial point is first guess but we have to make sure that we
  // are within the parameter domain
  for (i = 0; i < mVariableSize; i++)
    {
      const COptItem & OptItem = *(*mpOptItem)[i];

      switch (OptItem.checkConstraint())
        {
        case - 1:
          mIndividual[i] = *OptItem.getLowerBoundValue();
          (*(*mpSetCalculateVariable)[i])(mIndividual[i]);
          break;

        case 1:
          mIndividual[i] = *OptItem.getUpperBoundValue();
          (*(*mpSetCalculateVariable)[i])(mIndividual[i]);
          break;

        case 0:
          mIndividual[i] = *OptItem.getObjectValue();
          break;
        }
    }

  fmx = mBestValue = evaluate();

  mpOptProblem->setSolutionVariables(mIndividual);
  mContinue = mpOptProblem->setSolutionValue(mBestValue);

  // We found a new best value lets report it.
  //if (mpReport) mpReport->printBody();
  mpParentTask->doOutput();

  bool SolutionFound = false;

  for (mCurrentIteration = 0; mCurrentIteration < mIterations && mContinue && !SolutionFound; mCurrentIteration++)
    {
      // calculate the direction of steepest descent
      // by central finite differences
      gradient();
      // minimise the function in this direction
      // find brackets for the minimisation
      //  mn = 0.0; md = 1.0;
      //  mnbrak(&mn, &md, &mx, &fmn, &fmd, &fmx, descent_line);
      // make sure that no parameter will exceed its bounds
      x0 = DBL_MAX;

      for (i = 0; i < mVariableSize; i++)
        {
          if (fabs(mGradient[i]) > DBL_EPSILON)
            {
              if (mGradient[i] > 0)
                {
                  tmp = *(*mpOptItem)[i]->getUpperBoundValue();
                }

              else
                {
                  tmp = *(*mpOptItem)[i]->getLowerBoundValue();
                }

              // calculate the size of the largest jump
              tmp = (tmp - mIndividual[i]) / mGradient[i];
              // keep it if it is the smallest
              if (tmp < x0) x0 = tmp;
            }
          else mGradient[i] = 0.0;
        }

      if (x0 < mTolerance) x0 = mTolerance;

      // we will move at a rate of 1/10 this size
      mn = mx = alpha = 0.0;

      for (k = 0, calc_grad = false; (k < 9) && !calc_grad && !SolutionFound; k++)
        {
          // set the minimum to the last successful step
          mn = mx;
          fmn = fmx;
          // increment alpha
          alpha += 0.1 * x0;
          // set the maximum to it
          mx = alpha;

          // take one step in that direction
          fmx = descentLine(alpha);

          fmx = evaluate();

          // if this was an upward step find the minimum
          if (fmx > fmn)
            {
              //md = mn + (mx-mn)/2;
              //Brent(mn, md, mx, descent_line, &alpha, &tmp, 1e-6, 50);

              FminBrent(mn, mx, mpDescent, &alpha, &tmp, mTolerance, 5);

              // take one step in that direction
              fmx = descentLine(alpha);

              // time to evaluate the new steepest descent direction
              calc_grad = true;
            }

          if (fabs(fmx - mBestValue) < mTolerance)
            SolutionFound = true;
        }

      for (i = 0; i < mVariableSize; i++)
        mIndividual[i] = *(*mpOptItem)[i]->getObjectValue();

      if (fmx < mBestValue)
        {
          mBestValue = fmx;

          mpOptProblem->setSolutionVariables(mIndividual);
          mContinue = mpOptProblem->setSolutionValue(mBestValue);

          // We found a new best value lets report it.
          //if (mpReport) mpReport->printBody();
          mpParentTask->doOutput();
        }
    }

  return SolutionFound;
}

bool COptMethodSteepestDescent::cleanup()
{
  // pdelete all used variables
  return true;
}

bool COptMethodSteepestDescent::initialize()
{
  cleanup();

  if (!COptMethod::initialize()) return false;

  mIterations = * getValue("Iteration Limit").pUINT;
  mTolerance = * getValue("Tolerance").pDOUBLE;

  mContinue = true;
  mVariableSize = mpOptItem->size();
  mIndividual.resize(mVariableSize);
  mGradient.resize(mVariableSize);

  mBestValue = DBL_MAX;

  return true;
}

void COptMethodSteepestDescent::gradient()
{
  unsigned C_INT32 i;

  C_FLOAT64 y;
  C_FLOAT64 x;

  y = evaluate();

  for (i = 0; i < mVariableSize && mContinue; i++)
    {
      if ((x = *(*mpOptItem)[i]->getObjectValue()) != 0.0)
        {
          (*(*mpSetCalculateVariable)[i])(x * 1.001);
          mGradient[i] = (y - evaluate()) / (x * 0.001);
        }

      else
        {
          (*(*mpSetCalculateVariable)[i])(1e-7);
          mGradient[i] = (y - evaluate()) / 1e-7;
        }

      (*(*mpSetCalculateVariable)[i])(x);
    }
}

const C_FLOAT64 COptMethodSteepestDescent::descentLine(const C_FLOAT64 & x)
{
  for (unsigned C_INT32 i = 0; i < mVariableSize; i++)
    (*(*mpSetCalculateVariable)[i])(mIndividual[i] + x * mGradient[i]);

  return evaluate();
}

// evaluate the fitness of one individual
const C_FLOAT64 & COptMethodSteepestDescent::evaluate()
{
  // evaluate the fitness
  mContinue = mpOptProblem->calculate();

  mValue = mpOptProblem->getCalculateValue();

  // when we leave the either the parameter or functional domain
  // we penalize the objective value by forcing it to be larger
  // than the best value recorded so far.
  if (mValue < mBestValue &&
      (!mpOptProblem->checkParametricConstraints() ||
       !mpOptProblem->checkFunctionalConstraints()))
    mValue = mBestValue + fabs(mBestValue - mValue);

  return mValue;
}

void COptMethodSteepestDescent::initObjects()
{
  addObjectReference("Current Iteration", mCurrentIteration, CCopasiObject::ValueInt);
}
<commit_msg>Fixed to work with fitting.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptMethodSteepestDescent.cpp,v $
   $Revision: 1.14 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/11/06 22:17:03 $
   End CVS Header */

#include "copasi.h"

#include "COptMethod.h"
#include "COptProblem.h"
#include "COptItem.h"
#include "COptTask.h"

#include "FminBrent.h"

#include "report/CCopasiObjectReference.h"

COptMethodSteepestDescent::COptMethodSteepestDescent(const CCopasiContainer * pParent):
    COptMethod(CCopasiTask::optimization, CCopasiMethod::SteepestDescent, pParent),
    mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine))
{
  addParameter("Iteration Limit", CCopasiParameter::UINT, (unsigned C_INT32) 100);
  addParameter("Tolerance", CCopasiParameter::DOUBLE, (C_FLOAT64) 1e-6);
}

COptMethodSteepestDescent::COptMethodSteepestDescent(const COptMethodSteepestDescent & src,
    const CCopasiContainer * pParent): COptMethod(src, pParent),
    mpDescent(new FDescentTemplate<COptMethodSteepestDescent>(this, &COptMethodSteepestDescent::descentLine))
{}

COptMethodSteepestDescent::~COptMethodSteepestDescent()
{
  pdelete(mpDescent);

  cleanup();
}

bool COptMethodSteepestDescent::optimise()
{
  if (!initialize()) return false;

  unsigned C_INT32 i, k;
  C_FLOAT64 tmp, x0, alpha, mn, mx, fmn, fmx;
  bool calc_grad;

  // initial point is first guess but we have to make sure that we
  // are within the parameter domain
  for (i = 0; i < mVariableSize; i++)
    {
      const COptItem & OptItem = *(*mpOptItem)[i];

      switch (OptItem.checkConstraint())
        {
        case - 1:
          mIndividual[i] = *OptItem.getLowerBoundValue();
          break;

        case 1:
          mIndividual[i] = *OptItem.getUpperBoundValue();
          break;

        case 0:
          mIndividual[i] = *OptItem.getObjectValue();
          break;
        }

      (*(*mpSetCalculateVariable)[i])(mIndividual[i]);
    }

  fmx = mBestValue = evaluate();

  mpOptProblem->setSolutionVariables(mIndividual);
  mContinue = mpOptProblem->setSolutionValue(mBestValue);

  // We found a new best value lets report it.
  //if (mpReport) mpReport->printBody();
  mpParentTask->doOutput();

  bool SolutionFound = false;

  for (mCurrentIteration = 0; mCurrentIteration < mIterations && mContinue && !SolutionFound; mCurrentIteration++)
    {
      // calculate the direction of steepest descent
      // by central finite differences
      gradient();
      // minimise the function in this direction
      // find brackets for the minimisation
      //  mn = 0.0; md = 1.0;
      //  mnbrak(&mn, &md, &mx, &fmn, &fmd, &fmx, descent_line);
      // make sure that no parameter will exceed its bounds
      x0 = DBL_MAX;

      for (i = 0; i < mVariableSize; i++)
        {
          if (fabs(mGradient[i]) > DBL_EPSILON)
            {
              if (mGradient[i] > 0)
                {
                  tmp = *(*mpOptItem)[i]->getUpperBoundValue();
                }

              else
                {
                  tmp = *(*mpOptItem)[i]->getLowerBoundValue();
                }

              // calculate the size of the largest jump
              tmp = (tmp - mIndividual[i]) / mGradient[i];
              // keep it if it is the smallest
              if (tmp < x0) x0 = tmp;
            }
          else mGradient[i] = 0.0;
        }

      if (x0 < mTolerance) x0 = mTolerance;

      // we will move at a rate of 1/10 this size
      mn = mx = alpha = 0.0;

      for (k = 0, calc_grad = false; (k < 9) && !calc_grad && !SolutionFound; k++)
        {
          // set the minimum to the last successful step
          mn = mx;
          fmn = fmx;
          // increment alpha
          alpha += 0.1 * x0;
          // set the maximum to it
          mx = alpha;

          // take one step in that direction
          fmx = descentLine(alpha);

          fmx = evaluate();

          // if this was an upward step find the minimum
          if (fmx > fmn)
            {
              //md = mn + (mx-mn)/2;
              //Brent(mn, md, mx, descent_line, &alpha, &tmp, 1e-6, 50);

              FminBrent(mn, mx, mpDescent, &alpha, &tmp, mTolerance, 5);

              // take one step in that direction
              fmx = descentLine(alpha);

              // time to evaluate the new steepest descent direction
              calc_grad = true;
            }

          if (fabs(fmx - mBestValue) < mTolerance)
            SolutionFound = true;
        }

      for (i = 0; i < mVariableSize; i++)
        mIndividual[i] = *(*mpOptItem)[i]->getObjectValue();

      if (fmx < mBestValue)
        {
          mBestValue = fmx;

          mpOptProblem->setSolutionVariables(mIndividual);
          mContinue = mpOptProblem->setSolutionValue(mBestValue);

          // We found a new best value lets report it.
          //if (mpReport) mpReport->printBody();
          mpParentTask->doOutput();
        }
    }

  return SolutionFound;
}

bool COptMethodSteepestDescent::cleanup()
{
  // pdelete all used variables
  return true;
}

bool COptMethodSteepestDescent::initialize()
{
  cleanup();

  if (!COptMethod::initialize()) return false;

  mIterations = * getValue("Iteration Limit").pUINT;
  mTolerance = * getValue("Tolerance").pDOUBLE;

  mContinue = true;
  mVariableSize = mpOptItem->size();
  mIndividual.resize(mVariableSize);
  mGradient.resize(mVariableSize);

  mBestValue = DBL_MAX;

  return true;
}

void COptMethodSteepestDescent::gradient()
{
  unsigned C_INT32 i;

  C_FLOAT64 y;
  C_FLOAT64 x;

  y = evaluate();

  for (i = 0; i < mVariableSize && mContinue; i++)
    {
      if ((x = *(*mpOptItem)[i]->getObjectValue()) != 0.0)
        {
          (*(*mpSetCalculateVariable)[i])(x * 1.001);
          mGradient[i] = (y - evaluate()) / (x * 0.001);
        }

      else
        {
          (*(*mpSetCalculateVariable)[i])(1e-7);
          mGradient[i] = (y - evaluate()) / 1e-7;
        }

      (*(*mpSetCalculateVariable)[i])(x);
    }
}

const C_FLOAT64 COptMethodSteepestDescent::descentLine(const C_FLOAT64 & x)
{
  for (unsigned C_INT32 i = 0; i < mVariableSize; i++)
    (*(*mpSetCalculateVariable)[i])(mIndividual[i] + x * mGradient[i]);

  return evaluate();
}

// evaluate the fitness of one individual
const C_FLOAT64 & COptMethodSteepestDescent::evaluate()
{
  // evaluate the fitness
  mContinue = mpOptProblem->calculate();

  mValue = mpOptProblem->getCalculateValue();

  // when we leave the either the parameter or functional domain
  // we penalize the objective value by forcing it to be larger
  // than the best value recorded so far.
  if (mValue < mBestValue &&
      (!mpOptProblem->checkParametricConstraints() ||
       !mpOptProblem->checkFunctionalConstraints()))
    mValue = mBestValue + fabs(mBestValue - mValue);

  return mValue;
}

void COptMethodSteepestDescent::initObjects()
{
  addObjectReference("Current Iteration", mCurrentIteration, CCopasiObject::ValueInt);
}
<|endoftext|>


<commit_before>/**
 *   SFCGAL
 *
 *   Copyright (C) 2012-2013 Oslandia <infos@oslandia.com>
 *   Copyright (C) 2012-2013 IGN (http://www.ign.fr)
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <boost/test/unit_test.hpp>

#include <SFCGAL/Kernel.h>
#include <SFCGAL/all.h>
#include <SFCGAL/io/wkt.h>
#include <SFCGAL/algorithm/length.h>

using namespace boost::unit_test ;
using namespace SFCGAL ;

BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_LengthTest )

BOOST_AUTO_TEST_CASE( testZeroLength )
{
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("POINT(0.0 0.0)" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING EMPTY" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))" ) ), 0.0 );
}

BOOST_AUTO_TEST_CASE( testZeroLengthVertical )
{
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" ) ), 0.0 );
}

BOOST_AUTO_TEST_CASE( testLengthLineString )
{
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING(0.0 0.0,3.0 4.0)" ) ), 5.0 );
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING(0.0 0.0,0.0 1.0,1.0 1.0)" ) ), 2.0 );
}

//-- 3D

BOOST_AUTO_TEST_CASE( test3DZeroLength )
{
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("POINT(0.0 0.0)" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("LINESTRING EMPTY" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))" ) ), 0.0 );
}
BOOST_AUTO_TEST_CASE( test3DLengthVertical )
{
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" ) ), 1.0 );
}
BOOST_AUTO_TEST_CASE( test3DLengthLineString )
{
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("LINESTRING(0.0 0.0 0.0,0.0 1.0 0.0,0.0 1.0 1.0)" ) ), 2.0 );
}

BOOST_AUTO_TEST_SUITE_END()

<commit_msg>[algorithm::distance]add some tests<commit_after>/**
 *   SFCGAL
 *
 *   Copyright (C) 2012-2013 Oslandia <infos@oslandia.com>
 *   Copyright (C) 2012-2013 IGN (http://www.ign.fr)
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#include <boost/test/unit_test.hpp>

#include <SFCGAL/Kernel.h>
#include <SFCGAL/all.h>
#include <SFCGAL/io/wkt.h>
#include <SFCGAL/algorithm/length.h>

using namespace boost::unit_test ;
using namespace SFCGAL ;

BOOST_AUTO_TEST_SUITE( SFCGAL_algorithm_LengthTest )

BOOST_AUTO_TEST_CASE( testZeroLength )
{
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("POINT(0.0 0.0)" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING EMPTY" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))" ) ), 0.0 );
}

BOOST_AUTO_TEST_CASE( testZeroLengthVertical )
{
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" ) ), 0.0 );
}

BOOST_AUTO_TEST_CASE( testLengthLineString )
{
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING(0.0 0.0,3.0 4.0)" ) ), 5.0 );
	BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt("LINESTRING(0.0 0.0,0.0 1.0,1.0 1.0)" ) ), 2.0 );
}

//-- 3D

BOOST_AUTO_TEST_CASE( test3DZeroLength )
{
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("POINT(0.0 0.0)" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("LINESTRING EMPTY" ) ), 0.0 );
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("POLYGON((0 0,0 1,1 1,1 0,0 0))" ) ), 0.0 );
}
BOOST_AUTO_TEST_CASE( test3DLengthVertical )
{
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("LINESTRING(0.0 0.0 0.0,0.0 0.0 1.0)" ) ), 1.0 );
}
BOOST_AUTO_TEST_CASE( test3DLengthLineString )
{
	BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt("LINESTRING(0.0 0.0 0.0,0.0 1.0 0.0,0.0 1.0 1.0)" ) ), 2.0 );
}

//-- invalid type 2D

BOOST_AUTO_TEST_CASE( testLength_invalidType )
{
	std::vector< std::string > wkts ;
	wkts.push_back( "POINT(3.0 4.0)" );
	wkts.push_back( "TRIANGLE((0.0 0.0,1.0 0.0,1.0 1.0,0.0 0.0))" );
	wkts.push_back( "POLYGON((0.0 0.0,1.0 0.0,1.0 1.0,0.0 0.0))" );

	for ( size_t i = 0; i < wkts.size(); i++ ){
		BOOST_TEST_MESSAGE( wkts[i] );
		BOOST_CHECK_EQUAL( algorithm::length( *io::readWkt( wkts[i] ) ), 0.0 );
		BOOST_CHECK_EQUAL( algorithm::length3D( *io::readWkt( wkts[i] ) ), 0.0 );
	}

}
//-- invalid type 3D

BOOST_AUTO_TEST_SUITE_END()

<|endoftext|>


<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include "caf/config.hpp"
#include "caf/error.hpp"

#include "caf/detail/type_traits.hpp"

// The class `callback` intentionally has no virtual destructor, because
// the lifetime of callback objects is never managed via base pointers.
CAF_PUSH_NON_VIRTUAL_DTOR_WARNING

namespace caf {

/// Describes a simple callback, usually implemented via lambda expression.
/// Callbacks are used as "type-safe function objects" wherever an interface
/// requires dynamic dispatching. The alternative would be to store the lambda
/// in a `std::function`, which adds another layer of indirection and
/// requires a heap allocation. With the callback implementation of CAF,
/// the object remains on the stack and does not cause more overhead
/// than necessary.
template <class Signature>
class callback;

template <class Result, class... Ts>
class callback<Result(Ts...)> {
public:
  virtual Result operator()(Ts...) = 0;
};

/// Utility class for wrapping a function object of type `F`.
template <class F, class Signature>
class callback_impl;

template <class F, class Result, class... Ts>
class callback_impl<F, Result(Ts...)> : public callback<Result(Ts...)> {
public:
  callback_impl(F&& f) : f_(std::move(f)) {
    // nop
  }

  callback_impl(callback_impl&&) = default;

  callback_impl& operator=(callback_impl&&) = default;

  Result operator()(Ts... xs) override {
    return f_(std::forward<Ts>(xs)...);
  }

private:
  F f_;
};

/// Creates a ::callback from the function object `fun`.
/// @relates callback
template <class F>
auto make_callback(F fun) {
  using signature = typename detail::get_callable_trait<F>::fun_sig;
  return callback_impl<F, signature>{std::move(fun)};
}

} // namespace caf

CAF_POP_WARNINGS
<commit_msg>Add support for heap-allocated callbacks<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#pragma once

#include "caf/config.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/error.hpp"

#include <memory>

namespace caf {

/// Describes a simple callback, usually implemented via lambda expression.
/// Callbacks are used as "type-safe function objects" wherever an interface
/// requires dynamic dispatching. The alternative would be to store the lambda
/// in a `std::function`, which adds another layer of indirection and always
/// requires a heap allocation. With the callback implementation of CAF, the
/// object may remains on the stack and do not cause more overhead than
/// necessary.
template <class Signature>
class callback;

template <class Result, class... Ts>
class callback<Result(Ts...)> {
public:
  virtual ~callback() {
    // nop
  }

  virtual Result operator()(Ts...) = 0;
};

/// Smart pointer type for heap-allocated callbacks with unique ownership.
template <class Signature>
using unique_callback_ptr = std::unique_ptr<callback<Signature>>;

/// Smart pointer type for heap-allocated callbacks with shared ownership.
template <class Signature>
using shared_callback_ptr = std::shared_ptr<callback<Signature>>;

/// Utility class for wrapping a function object of type `F`.
template <class F, class Signature>
class callback_impl;

template <class F, class Result, class... Ts>
class callback_impl<F, Result(Ts...)> final : public callback<Result(Ts...)> {
public:
  callback_impl(F&& f) : f_(std::move(f)) {
    // nop
  }

  callback_impl(callback_impl&&) = default;

  callback_impl& operator=(callback_impl&&) = default;

  Result operator()(Ts... xs) override {
    return f_(std::forward<Ts>(xs)...);
  }

private:
  F f_;
};

/// Wraps `fun` into a @ref callback function object.
/// @relates callback
template <class F>
auto make_callback(F fun) {
  using signature = typename detail::get_callable_trait<F>::fun_sig;
  return callback_impl<F, signature>{std::move(fun)};
}

/// Creates a heap-allocated, type-erased @ref callback from the function object
/// `fun`.
/// @relates callback
template <class F>
auto make_type_erased_callback(F fun) {
  using signature = typename detail::get_callable_trait<F>::fun_sig;
  using result_t = unique_callback_ptr<signature>;
  return result_t{new callback_impl<F, signature>{std::move(fun)}};
}

/// Creates a heap-allocated, type-erased @ref callback from the function object
/// `fun` with shared ownership.
/// @relates callback
template <class F>
auto make_shared_type_erased_callback(F fun) {
  using signature = typename detail::get_callable_trait<F>::fun_sig;
  auto res = std::make_shared<callback_impl<F, signature>>(std::move(fun));
  return shared_callback_ptr<signature>{std::move(res)};
}

} // namespace caf
<|endoftext|>


<commit_before>#include "NL_DeviceCore.h"

#include "NL_Clock.h"
#include "NL_System.h"
#include "NL_SysManager.h"
#include "NL_Scheduler.h"
#include "NL_StateManager.h"
#include "NL_IEngine.h"

#include <cassert>

namespace NLE
{
	namespace Core
	{
		DeviceCore *DeviceCore::_deviceCore = nullptr;

		DeviceCore::DeviceCore() :
			_initialized(false)
		{
			_clock = std::make_unique<Clock>();
			_sysManager = std::make_unique<SysManager>();
			_scheduler = std::make_unique<Scheduler>();
			_stateManager = std::make_unique<StateManager>();
			_iEngine = std::make_unique<IEngine>(_scheduler, _sysManager, _stateManager);
		}

		DeviceCore::~DeviceCore()
		{
			release();
		}

		bool DeviceCore::initialize()
		{
			assert(!_initialized);

			std::unique_ptr<Scheduler>& scheduler = _scheduler;
			std::unique_ptr<SysManager>& sysMngr = _sysManager;
			std::unique_ptr<StateManager>& stateMngr = _stateManager;

			if (!_clock->initialize([&scheduler, &sysMngr, &stateMngr](){
				printf("Tick...\n");
				scheduler->manageExecution(sysMngr, stateMngr);
			}))
				return false;

			if (!_scheduler->initialize())
				return false;
			if (!_sysManager->initialize(_scheduler, _iEngine))
				return false;
			if (!_stateManager->initialize())
				return false;

			_initialized = true;
			return true;
		}

		void DeviceCore::release()
		{
			if (_sysManager)
				_sysManager->release();
			if (_stateManager)
				_stateManager->release();
			if (_scheduler)
				_scheduler->release();
			if (_clock)
				_clock->release();

			_initialized = false;
		}

		void DeviceCore::attachSystem(uint_fast32_t sysId, ExecutionDesc executionDesc, std::unique_ptr<System> system)
		{
			_sysManager->attachSystem(sysId, executionDesc, std::move(system));
		}

		void DeviceCore::setClockPeriodNs(unsigned long long periodNs)
		{
			_clock->setPeriodNs(periodNs);
		}

		void DeviceCore::setNumThreads(uint_fast32_t numThreads)
		{
			_scheduler->setNumThreads(numThreads);
		}

		uint_fast32_t DeviceCore::getNumHardwareThreads()
		{
			return _scheduler->getNumHardwareThreads();
		}

		void DeviceCore::run()
		{
			_clock->run();
		}

		void DeviceCore::stop()
		{
			_clock->stop();
		}
	}
}<commit_msg>core can only be ran when initialized<commit_after>#include "NL_DeviceCore.h"

#include "NL_Clock.h"
#include "NL_System.h"
#include "NL_SysManager.h"
#include "NL_Scheduler.h"
#include "NL_StateManager.h"
#include "NL_IEngine.h"

#include <cassert>

namespace NLE
{
	namespace Core
	{
		DeviceCore *DeviceCore::_deviceCore = nullptr;

		DeviceCore::DeviceCore() :
			_initialized(false)
		{
			_clock = std::make_unique<Clock>();
			_sysManager = std::make_unique<SysManager>();
			_scheduler = std::make_unique<Scheduler>();
			_stateManager = std::make_unique<StateManager>();
			_iEngine = std::make_unique<IEngine>(_scheduler, _sysManager, _stateManager);
		}

		DeviceCore::~DeviceCore()
		{
			release();
		}

		bool DeviceCore::initialize()
		{
			assert(!_initialized);

			std::unique_ptr<Scheduler>& scheduler = _scheduler;
			std::unique_ptr<SysManager>& sysMngr = _sysManager;
			std::unique_ptr<StateManager>& stateMngr = _stateManager;

			if (!_clock->initialize([&scheduler, &sysMngr, &stateMngr](){
				printf("Tick...\n");
				scheduler->manageExecution(sysMngr, stateMngr);
			}))
				return false;

			if (!_scheduler->initialize())
				return false;
			if (!_sysManager->initialize(_scheduler, _iEngine))
				return false;
			if (!_stateManager->initialize())
				return false;

			_initialized = true;
			return true;
		}

		void DeviceCore::release()
		{
			if (_sysManager)
				_sysManager->release();
			if (_stateManager)
				_stateManager->release();
			if (_scheduler)
				_scheduler->release();
			if (_clock)
				_clock->release();

			_initialized = false;
		}

		void DeviceCore::attachSystem(uint_fast32_t sysId, ExecutionDesc executionDesc, std::unique_ptr<System> system)
		{
			_sysManager->attachSystem(sysId, executionDesc, std::move(system));
		}

		void DeviceCore::setClockPeriodNs(unsigned long long periodNs)
		{
			_clock->setPeriodNs(periodNs);
		}

		void DeviceCore::setNumThreads(uint_fast32_t numThreads)
		{
			_scheduler->setNumThreads(numThreads);
		}

		uint_fast32_t DeviceCore::getNumHardwareThreads()
		{
			return _scheduler->getNumHardwareThreads();
		}

		void DeviceCore::run()
		{
			assert(_initialized);
			_clock->run();
		}

		void DeviceCore::stop()
		{
			_clock->stop();
		}
	}
}<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

// Quicksort
void quickSort(int a[], int p, int r);
int partition(int a[], int p, int r);
// BubbleSort
void bubbleSort(int array[]);

main(int argc, char** argv)
{
        if (argc != 2)
	{
                printf("Nope! Like this: ./bubbles n\n");
                return 0;
        }

        int userNum = atoi(&argv[1][0]);
	cout << "userNum: " << userNum << endl;
	int array[userNum + 1]; // creates array to hold names
	int n = 0;
	ifstream myfile ("../../size1000/list998"); //opening the file.

	if(myfile.is_open()) //if the file is open
	{
		while (!myfile.eof() && (n < userNum)) //while the end of file is NOT reached
		{
			myfile >> array[n];
            		n++;
        	}
		array[n] = '\0';
		myfile.close(); //closing the file

	}
	else cout << "Unable to open file"; //if the file is not open output

	n = 0;
        cout << "unsorted list:\n{";
        while (array[n] != '\0')
        {
                cout << array[n] << ", ";
                ++n;
        }
        cout << "}\n";

	int t1 = clock();
        //bubbleSort(array);
	int t2 = clock();
	quickSort(array, 0, 1000);
	int t3 = clock();
        n = 0;
        cout << "sorted list:\n{";
        while (array[n] != '\0')
        {
                cout << array[n] << ", ";
                ++n;
        }
        cout << "}\n";
	cout << "t1: " << t1 << ", t2: " << t2 << endl;
	cout << "BubbleSort execution time on n = "<< userNum << ": " << t2-t1 << endl;
	return 0;
}

void bubbleSort(int array[])
{
        int swap;
        do{
                swap = 0;
                int n = 1;
                while (array[n] != '\0')
                {
                        if (array[n-1] > array[n])
                        {
                                swap = 1;
                                int temp = array[n-1];
                                array[n-1] = array[n];
                                array[n] = temp;
                        }
                        ++n;
                }
        }while(swap == 1);
}
int partition(int a[], int p, int r) {
  int x = a[r];
  int j = p - 1;
  for (int i = p; i < r; i++) {

    if (x <= a[i]) {
      j = j + 1;
      int temp = a[j];
      a[j] = a[i];
      a[i] = temp;
    }
  }
  a[r] = a[j + 1];
  a[j + 1] = x;

  return (j + 1);
}
void quickSort(int a[], int p, int r) {
  if (p < r) {
    int q = partition(a, p, r);
    quickSort(a, p, q - 1);
    quickSort(a, q + 1, r);
  }
}
<commit_msg>added insertion. now have bbl, ins, quick<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <sys/time.h>
using namespace std;

// Quicksort
void quickSort(int a[], int p, int r);
int partition(int a[], int p, int r);

// BubbleSort
void bubbleSort(int array[]);

// InsertionSort
void insertionSort(int arr[], int length);

// Get unsorted lists of integers
void getList(int array[], int userNum);

// Print array contents
void printList(int array[]);

main(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Nope! Like this: ./allSort n\n");
        return 0;
    }

    int userNum = atoi(&argv[1][0]);
    int array[userNum + 1]; // creates array to hold names
    getList(array, userNum);

    /*
       cout << "unsorted list:\n{";
       printList(array);
       cout << "}\n";
     */

    timeval t1;
    timeval t2;

    // Bubble Sort
    gettimeofday(&t1, NULL);
    bubbleSort(array);
    gettimeofday(&t2, NULL);

    /*
       cout << "bubbleSorted list:\n{";
       printList(array);
       cout << "}\n";

     */
    //cout << "t1: " << t1.tv_usec << ", t2: " << t2.tv_usec << endl;
    cout << "bubbleSort execution time on n = "<< userNum << ": " << t2.tv_usec - t1.tv_usec << endl;

    getList(array, userNum);

    /*
       cout << "unsorted list:\n{";
       printList(array);
       cout << "}\n";
     */

    // Quick Sort
    gettimeofday(&t1, NULL);
    quickSort(array, 0, 1000);
    gettimeofday(&t2, NULL);

    /*
       cout << "quickSorted list:\n{";
       printList(array);
       cout << "}\n";

       cout << "t1: " << t1 << ", t2: " << t2 << endl;
     */
    cout << "quickSort execution time on n = "<< userNum << ": " << t2.tv_usec - t1.tv_usec << endl;

    getList(array, userNum);

	/*
	cout << "unSorted list:\n{";
    	printList(array);
    	cout << "}\n";
	*/

    gettimeofday(&t1, NULL);
    insertionSort(array, userNum);
    gettimeofday(&t2, NULL);

	/*
    cout << "insertionSorted list:\n{";
    printList(array);
    cout << "}\n";
	*/

    cout << "insertionSort execution time on n = "<< userNum << ": " << t2.tv_usec - t1.tv_usec << endl;

    return 0;
}

void bubbleSort(int array[])
{
    int swap;
    do{
        swap = 0;
        int n = 1;
        while (array[n] != '\0')
        {
            if (array[n-1] > array[n])
            {
                swap = 1;
                int temp = array[n-1];
                array[n-1] = array[n];
                array[n] = temp;
            }
            ++n;
        }
    }while(swap == 1);
}

int partition(int a[], int p, int r) {
    int x = a[r];
    int j = p - 1;
    for (int i = p; i < r; i++) {

        if (x <= a[i]) {
            j = j + 1;
            int temp = a[j];
            a[j] = a[i];
            a[i] = temp;
        }
    }
    a[r] = a[j + 1];
    a[j + 1] = x;

    return (j + 1);
}

void quickSort(int a[], int p, int r) {
    if (p < r) {
        int q = partition(a, p, r);
        quickSort(a, p, q - 1);
        quickSort(a, q + 1, r);
    }
}

void getList(int array[], int userNum)
{
    int n = 0;

    ifstream myfile ("../../size1000/list998"); //opening the file.
    if(myfile.is_open()) //if the file is open
    {
        while (!myfile.eof() && (n < userNum)) //while the end of file is NOT reached
        {
            myfile >> array[n];
            n++;
        }
        array[n] = '\0';
        myfile.close(); //closing the file

    }
    else cout << "Unable to open file"; //if the file is not open output
}

void printList(int array[])
{
    int n = 0;
    while (array[n] != '\0')
    {
        cout << array[n] << ", ";
        ++n;
    }
}

void insertionSort(int arr[], int length)
{

    int i, j, tmp;
    for (i = 1; i < length; i++)
    {
        j = i;
        while (j > 0 && arr[j - 1] > arr[j])
        {
            tmp = arr[j];
            arr[j] = arr[j - 1];
            arr[j - 1] = tmp;
            j--;

        }

    }

}
<|endoftext|>


<commit_before>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "COptMethodTruncatedNewton.h"
#include "COptProblem.h"
#include "COptItem.h"
#include "COptTask.h"

#include "parameterFitting/CFitProblem.h"
#include "copasi/core/CDataObjectReference.h"

COptMethodTruncatedNewton::COptMethodTruncatedNewton(const CDataContainer * pParent,
    const CTaskEnum::Method & methodType,
    const CTaskEnum::Task & taskType):
  COptMethod(pParent, methodType, taskType),
  mpTruncatedNewton(new FTruncatedNewtonTemplate<COptMethodTruncatedNewton>(this, &COptMethodTruncatedNewton::sFun)),
  mpCTruncatedNewton(new CTruncatedNewton())
{
  initObjects();
}

COptMethodTruncatedNewton::COptMethodTruncatedNewton(const COptMethodTruncatedNewton & src,
    const CDataContainer * pParent):
  COptMethod(src, pParent),
  mpTruncatedNewton(new FTruncatedNewtonTemplate<COptMethodTruncatedNewton>(this, &COptMethodTruncatedNewton::sFun)),
  mpCTruncatedNewton(new CTruncatedNewton())
{initObjects();}

COptMethodTruncatedNewton::~COptMethodTruncatedNewton()
{
  pdelete(mpTruncatedNewton);
  pdelete(mpCTruncatedNewton);
  cleanup();
}

void COptMethodTruncatedNewton::initObjects()
{
  addObjectReference("Current Iteration", mIteration, CDataObject::ValueInt);
}

bool COptMethodTruncatedNewton::optimise()
{
  if (!initialize()) return false;

  if (mLogVerbosity > 0)
    mMethodLog.enterLogEntry(
      COptLogEntry(
        "Algorithm started",
        "For more information about this method see: http://copasi.org/Support/User_Manual/Methods/Optimization_Methods/Truncated_Newton/"
      )
    );

  C_FLOAT64 fest;
  C_INT lw, ierror = 0;
  lw = 14 * mVariableSize;

  CVector< C_FLOAT64 > up(mVariableSize);
  CVector< C_FLOAT64 > low(mVariableSize);
  CVector< C_INT > iPivot(mVariableSize);
  CVector< C_FLOAT64 > dwork(lw);

  up = std::numeric_limits< C_FLOAT64 >::max();
  low = - std::numeric_limits< C_FLOAT64 >::max();

  // initial point is the first guess but we have to make sure that
  // we are within the parameter domain
  C_INT i, repeat;
  bool pointInParameterDomain = true;

  for (i = 0; i < mVariableSize; i++)
    {
      const COptItem & OptItem = *(*mpOptItem)[i];

      // :TODO: In COPASI the bounds are not necessarry fixed.
      // Since evaluate checks for boundaries and constraints this is not
      // needed. The question remaining is how does tnbc_ handle unconstraint problems?
      // low[i] = *OptItem.getLowerBoundValue();
      // up[i] = *OptItem.getUpperBoundValue();

      mCurrent[i] = OptItem.getStartValue();

      switch (OptItem.checkConstraint(mCurrent[i]))
        {
          case - 1:
            mCurrent[i] = *OptItem.getLowerBoundValue();
            pointInParameterDomain = false;
            break;

          case 1:
            mCurrent[i] = *OptItem.getUpperBoundValue();
            pointInParameterDomain = false;
            break;

          case 0:
            break;
        }

      // set the value
      *mContainerVariables[i] = (mCurrent[i]);
    }

  if (!pointInParameterDomain && (mLogVerbosity > 0))
    mMethodLog.enterLogEntry(COptLogEntry("Initial point outside parameter domain."));

  // Report the first value as the current best
  mBestValue = evaluate();
  mBest = mCurrent;
  mContinue = mpOptProblem->setSolution(mBestValue, mBest);

  repeat = 0;

  while (repeat < 10 && mContinue)
    {
      repeat++;

      // estimate minimum is 1/10 initial function value
      fest = (1 - pow(0.9, (C_FLOAT64) repeat)) * mEvaluationValue;
      ierror = 0;

      // minimise
      try
        {
          mpCTruncatedNewton->tnbc_(&ierror, &mVariableSize, mCurrent.array(), &fest, mGradient.array(), dwork.array(), &lw, mpTruncatedNewton, low.array(), up.array(), iPivot.array());

          mEvaluationValue = fest;
        }

      // This signals that the user opted to interrupt
      catch (bool)
        {
          break;
        }

      if (ierror < 0)
        fatalError(); // Invalid parameter values.

      // The way the method is currently implemented may lead to parameters just outside the boundaries.
      // We need to check whether the current value is within the boundaries or whether the corrected
      // leads to an improved solution.

      bool withinBounds = true;

      for (i = 0; i < mVariableSize; i++)
        {
          const COptItem & OptItem = *(*mpOptItem)[i];

          //force it to be within the bounds
          switch (OptItem.checkConstraint(mCurrent[i]))
            {
              case - 1:
                withinBounds = false;
                mCurrent[i] = *OptItem.getLowerBoundValue();
                break;

              case 1:
                withinBounds = false;
                mCurrent[i] = *OptItem.getUpperBoundValue();
                break;

              case 0:
                break;
            }

          *mContainerVariables[i] = (mCurrent[i]);
        }

      evaluate();

      // Is the corrected value better than solution?
      if (mEvaluationValue < mBestValue)
        {
          // We found a new best value lets report it.
          // and store that value
          mBest = mCurrent;
          mBestValue = mEvaluationValue;

          mContinue = mpOptProblem->setSolution(mBestValue, mBest);

          // We found a new best value lets report it.
          mpParentTask->output(COutputInterface::DURING);
        }

      // We found a solution
      if (withinBounds)
        break;

      // Choosing another starting point will be left to the user
#ifdef XXXX

      // Try another starting point
      for (i = 0; i < mVariableSize; i++)
        {
          mCurrent[i] *= 1.2;
          const COptItem & OptItem = *(*mpOptItem)[i];

          //force it to be within the bounds
          switch (OptItem.checkConstraint(mCurrent[i]))
            {
              case - 1:
                mCurrent[i] = *OptItem.getLowerBoundValue();
                break;

              case 1:
                mCurrent[i] = *OptItem.getUpperBoundValue();
                break;

              case 0:
                break;
            }

          *mContainerVariables[i] = (mCurrent[i]);
        }

      evaluate();

      // Check whether we improved
      if (mEvaluationValue < mBestValue)
        {
          // We found a new best value lets report it.
          // and store that value
          mBest = mCurrent;
          mBestValue = mEvaluationValue;

          mContinue = mpOptProblem->setSolution(mBestValue, mBest);

          // We found a new best value lets report it.
          mpParentTask->output(COutputInterface::DURING);
        }

#endif // XXXX

      if (mLogVerbosity > 0)
        mMethodLog.enterLogEntry(
          COptLogEntry(
            "Solution parameters outside of the boundaries. Repeating calculations from current border position ("
            + std::to_string(repeat) + ")")
        );
    }

  if (mLogVerbosity > 0)
    mMethodLog.enterLogEntry(COptLogEntry("Algorithm finished."));

  return true;
}

bool COptMethodTruncatedNewton::initialize()
{
  cleanup();

  if (!COptMethod::initialize()) return false;

  mVariableSize = (C_INT) mpOptItem->size();
  mCurrent.resize(mVariableSize);
  mBest.resize(mVariableSize);

  mContinue = true;
  mBestValue = std::numeric_limits<C_FLOAT64>::infinity();
  mGradient.resize(mVariableSize);

  return true;
}

bool COptMethodTruncatedNewton::cleanup()
{
  return true;
}

// callback function, evaluate the value of the objective function and its gradient
//(by finite differences), translated by f2c, edited by Pedro and then modified for COPASI by Joseph
C_INT COptMethodTruncatedNewton::sFun(C_INT *n, C_FLOAT64 *x, C_FLOAT64 *f, C_FLOAT64 *g)
{
  C_INT i;

  // set the parameter values
  for (i = 0; i < *n; i++)
    *mContainerVariables[i] = (x[i]);

  //carry out the function evaluation
  *f = evaluate();

  // Check whether we improved
  if (mEvaluationValue < mBestValue)
    {
      // We found a new best value lets report it.
      // and store that value
      for (i = 0; i < *n; i++)
        mBest[i] = x[i];

      mBestValue = mEvaluationValue;
      mContinue = mpOptProblem->setSolution(mBestValue, mBest);

      // We found a new best value lets report it.
      mpParentTask->output(COutputInterface::DURING);
    }

  // Calculate the gradient
  for (i = 0; i < *n && mContinue; i++)
    {
      if (x[i] != 0.0)
        {
          *mContainerVariables[i] = (x[i] * 1.001);
          g[i] = (evaluate() - *f) / (x[i] * 0.001);
        }

      else
        {
          *mContainerVariables[i] = (1e-7);
          g[i] = (evaluate() - *f) / 1e-7;
        }

      *mContainerVariables[i] = (x[i]);
    }

  if (!mContinue)
    throw bool(mContinue);

  return 0;
}

const C_FLOAT64 & COptMethodTruncatedNewton::evaluate()
{
  // We do not need to check whether the parametric constraints are fulfilled
  // since the parameters are created within the bounds.
  mContinue = mpOptProblem->calculate();
  mEvaluationValue = mpOptProblem->getCalculateValue();

  // when we leave the either the parameter or functional domain
  // we penalize the objective value by forcing it to be larger
  // than the best value recorded so far.
  if (mEvaluationValue < mBestValue &&
      (!mpOptProblem->checkParametricConstraints() ||
       !mpOptProblem->checkFunctionalConstraints()))
    mEvaluationValue = mBestValue + mBestValue - mEvaluationValue;

  return mEvaluationValue;
}

unsigned C_INT32 COptMethodTruncatedNewton::getMaxLogVerbosity() const
{
  return 1;
}
<commit_msg>pass pointer to log to deeper functions for debug output<commit_after>// Copyright (C) 2017 - 2018 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and University of
// of Connecticut School of Medicine.
// All rights reserved.

// Copyright (C) 2010 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

// Copyright (C) 2008 - 2009 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., EML Research, gGmbH, University of Heidelberg,
// and The University of Manchester.
// All rights reserved.

// Copyright (C) 2007 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc. and EML Research, gGmbH.
// All rights reserved.

#include "copasi.h"

#include "COptMethodTruncatedNewton.h"
#include "COptProblem.h"
#include "COptItem.h"
#include "COptTask.h"

#include "parameterFitting/CFitProblem.h"
#include "copasi/core/CDataObjectReference.h"

COptMethodTruncatedNewton::COptMethodTruncatedNewton(const CDataContainer * pParent,
    const CTaskEnum::Method & methodType,
    const CTaskEnum::Task & taskType):
  COptMethod(pParent, methodType, taskType),
  mpTruncatedNewton(new FTruncatedNewtonTemplate<COptMethodTruncatedNewton>(this, &COptMethodTruncatedNewton::sFun)),
  mpCTruncatedNewton(new CTruncatedNewton())
{
  initObjects();
}

COptMethodTruncatedNewton::COptMethodTruncatedNewton(const COptMethodTruncatedNewton & src,
    const CDataContainer * pParent):
  COptMethod(src, pParent),
  mpTruncatedNewton(new FTruncatedNewtonTemplate<COptMethodTruncatedNewton>(this, &COptMethodTruncatedNewton::sFun)),
  mpCTruncatedNewton(new CTruncatedNewton())
{initObjects();}

COptMethodTruncatedNewton::~COptMethodTruncatedNewton()
{
  pdelete(mpTruncatedNewton);
  pdelete(mpCTruncatedNewton);
  cleanup();
}

void COptMethodTruncatedNewton::initObjects()
{
  addObjectReference("Current Iteration", mIteration, CDataObject::ValueInt);
}

bool COptMethodTruncatedNewton::optimise()
{
  if (!initialize()) return false;

  if (mLogVerbosity > 0)
    mMethodLog.enterLogEntry(
      COptLogEntry(
        "Truncated Newton algorithm started",
        "For more information about this method see: http://copasi.org/Support/User_Manual/Methods/Optimization_Methods/Truncated_Newton/"
      )
    );

  C_FLOAT64 fest;
  C_INT lw, ierror = 0;
  lw = 14 * mVariableSize;

  CVector< C_FLOAT64 > up(mVariableSize);
  CVector< C_FLOAT64 > low(mVariableSize);
  CVector< C_INT > iPivot(mVariableSize);
  CVector< C_FLOAT64 > dwork(lw);

  up = std::numeric_limits< C_FLOAT64 >::max();
  low = - std::numeric_limits< C_FLOAT64 >::max();

  // initial point is the first guess but we have to make sure that
  // we are within the parameter domain
  C_INT i, repeat;
  bool pointInParameterDomain = true;

  for (i = 0; i < mVariableSize; i++)
    {
      const COptItem & OptItem = *(*mpOptItem)[i];

      // :TODO: In COPASI the bounds are not necessarry fixed.
      // Since evaluate checks for boundaries and constraints this is not
      // needed. The question remaining is how does tnbc_ handle unconstraint problems?
      // low[i] = *OptItem.getLowerBoundValue();
      // up[i] = *OptItem.getUpperBoundValue();

      mCurrent[i] = OptItem.getStartValue();

      switch (OptItem.checkConstraint(mCurrent[i]))
        {
          case - 1:
            mCurrent[i] = *OptItem.getLowerBoundValue();
            pointInParameterDomain = false;
            break;

          case 1:
            mCurrent[i] = *OptItem.getUpperBoundValue();
            pointInParameterDomain = false;
            break;

          case 0:
            break;
        }

      // set the value
      *mContainerVariables[i] = (mCurrent[i]);
    }

  if (!pointInParameterDomain && (mLogVerbosity > 0))
    mMethodLog.enterLogEntry(COptLogEntry("Initial point outside parameter domain."));

  // Report the first value as the current best
  mBestValue = evaluate();
  mBest = mCurrent;
  mContinue = mpOptProblem->setSolution(mBestValue, mBest);

  repeat = 0;

  //tnbc_ wants a signed int for loglevel...
  C_INT msglvl;
  msglvl = (int) mLogVerbosity;

  while (repeat < 10 && mContinue)
    {
      repeat++;

      // estimate minimum is 1/10 initial function value
      fest = (1 - pow(0.9, (C_FLOAT64) repeat)) * mEvaluationValue;
      ierror = 0;

      // minimise
      try
        {
          mpCTruncatedNewton->tnbc_(&ierror,
                                    &mVariableSize,
                                    mCurrent.array(),
                                    &fest,
                                    mGradient.array(),
                                    dwork.array(),
                                    &lw,
                                    mpTruncatedNewton,
                                    low.array(),
                                    up.array(),
                                    iPivot.array(),
                                    &msglvl,
                                    &mMethodLog);

          mEvaluationValue = fest;
        }

      // This signals that the user opted to interrupt
      catch (bool)
        {
          break;
        }

      if (ierror < 0)
        fatalError(); // Invalid parameter values.

      // The way the method is currently implemented may lead to parameters just outside the boundaries.
      // We need to check whether the current value is within the boundaries or whether the corrected
      // leads to an improved solution.

      bool withinBounds = true;

      for (i = 0; i < mVariableSize; i++)
        {
          const COptItem & OptItem = *(*mpOptItem)[i];

          //force it to be within the bounds
          switch (OptItem.checkConstraint(mCurrent[i]))
            {
              case - 1:
                withinBounds = false;
                mCurrent[i] = *OptItem.getLowerBoundValue();
                break;

              case 1:
                withinBounds = false;
                mCurrent[i] = *OptItem.getUpperBoundValue();
                break;

              case 0:
                break;
            }

          *mContainerVariables[i] = (mCurrent[i]);
        }

      evaluate();

      // Is the corrected value better than solution?
      if (mEvaluationValue < mBestValue)
        {
          // We found a new best value lets report it.
          // and store that value
          mBest = mCurrent;
          mBestValue = mEvaluationValue;

          mContinue = mpOptProblem->setSolution(mBestValue, mBest);

          // We found a new best value lets report it.
          mpParentTask->output(COutputInterface::DURING);
        }

      // We found a solution
      if (withinBounds)
        break;

      // Choosing another starting point will be left to the user
#ifdef XXXX

      // Try another starting point
      for (i = 0; i < mVariableSize; i++)
        {
          mCurrent[i] *= 1.2;
          const COptItem & OptItem = *(*mpOptItem)[i];

          //force it to be within the bounds
          switch (OptItem.checkConstraint(mCurrent[i]))
            {
              case - 1:
                mCurrent[i] = *OptItem.getLowerBoundValue();
                break;

              case 1:
                mCurrent[i] = *OptItem.getUpperBoundValue();
                break;

              case 0:
                break;
            }

          *mContainerVariables[i] = (mCurrent[i]);
        }

      evaluate();

      // Check whether we improved
      if (mEvaluationValue < mBestValue)
        {
          // We found a new best value lets report it.
          // and store that value
          mBest = mCurrent;
          mBestValue = mEvaluationValue;

          mContinue = mpOptProblem->setSolution(mBestValue, mBest);

          // We found a new best value lets report it.
          mpParentTask->output(COutputInterface::DURING);
        }

#endif // XXXX

      if (mLogVerbosity > 0)
        mMethodLog.enterLogEntry(
          COptLogEntry(
            "Solution parameters outside of the boundaries. Repeating calculations from current border position ("
            + std::to_string(repeat) + ")")
        );
    }

  if (mLogVerbosity > 0)
    mMethodLog.enterLogEntry(COptLogEntry("Algorithm finished."));

  return true;
}

bool COptMethodTruncatedNewton::initialize()
{
  cleanup();

  if (!COptMethod::initialize()) return false;

  mVariableSize = (C_INT) mpOptItem->size();
  mCurrent.resize(mVariableSize);
  mBest.resize(mVariableSize);

  mContinue = true;
  mBestValue = std::numeric_limits<C_FLOAT64>::infinity();
  mGradient.resize(mVariableSize);

  return true;
}

bool COptMethodTruncatedNewton::cleanup()
{
  return true;
}

// callback function, evaluate the value of the objective function and its gradient
//(by finite differences), translated by f2c, edited by Pedro and then modified for COPASI by Joseph
C_INT COptMethodTruncatedNewton::sFun(C_INT *n, C_FLOAT64 *x, C_FLOAT64 *f, C_FLOAT64 *g)
{
  C_INT i;

  // set the parameter values
  for (i = 0; i < *n; i++)
    *mContainerVariables[i] = (x[i]);

  //carry out the function evaluation
  *f = evaluate();

  // Check whether we improved
  if (mEvaluationValue < mBestValue)
    {
      // We found a new best value lets report it.
      // and store that value
      for (i = 0; i < *n; i++)
        mBest[i] = x[i];

      mBestValue = mEvaluationValue;
      mContinue = mpOptProblem->setSolution(mBestValue, mBest);

      // We found a new best value lets report it.
      mpParentTask->output(COutputInterface::DURING);
    }

  // Calculate the gradient
  for (i = 0; i < *n && mContinue; i++)
    {
      if (x[i] != 0.0)
        {
          *mContainerVariables[i] = (x[i] * 1.001);
          g[i] = (evaluate() - *f) / (x[i] * 0.001);
        }

      else
        {
          *mContainerVariables[i] = (1e-7);
          g[i] = (evaluate() - *f) / 1e-7;
        }

      *mContainerVariables[i] = (x[i]);
    }

  if (!mContinue)
    throw bool(mContinue);

  return 0;
}

const C_FLOAT64 & COptMethodTruncatedNewton::evaluate()
{
  // We do not need to check whether the parametric constraints are fulfilled
  // since the parameters are created within the bounds.
  mContinue = mpOptProblem->calculate();
  mEvaluationValue = mpOptProblem->getCalculateValue();

  // when we leave the either the parameter or functional domain
  // we penalize the objective value by forcing it to be larger
  // than the best value recorded so far.
  if (mEvaluationValue < mBestValue &&
      (!mpOptProblem->checkParametricConstraints() ||
       !mpOptProblem->checkFunctionalConstraints()))
    mEvaluationValue = mBestValue + mBestValue - mEvaluationValue;

  return mEvaluationValue;
}

unsigned C_INT32 COptMethodTruncatedNewton::getMaxLogVerbosity() const
{
  return 1;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: zoom.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2008-03-07 15:17:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/
#ifndef _SVX_ZOOM_HXX
#define _SVX_ZOOM_HXX

// include ---------------------------------------------------------------

#include <layout/layout.hxx>
#ifndef _BASEDLGS_HXX //autogen wg. SfxModalDialog
#include <sfx2/basedlgs.hxx>
#endif
#ifndef _SV_BUTTON_HXX //autogen wg. Radio-/OK-/Cancel-/HelpButton
#include <vcl/button.hxx>
#endif
#ifndef _SV_FIELD_HXX //autogen wg. MetricField
#include <vcl/field.hxx>
#endif
#ifndef _SV_FIXED_HXX
#include <vcl/fixed.hxx>
#endif

// define ----------------------------------------------------------------
/* CHINA001
#define ZOOMBTN_OPTIMAL     ((USHORT)0x0001)
#define ZOOMBTN_PAGEWIDTH   ((USHORT)0x0002)
#define ZOOMBTN_WHOLEPAGE   ((USHORT)0x0004)
*/
#ifndef _SVX_ZOOM_HXX
#include "zoom_def.hxx"
#endif
// class SvxZoomDialog ---------------------------------------------------
/*
    {k:\svx\prototyp\dialog\zoom.bmp}

    [Beschreibung]
    Mit diesem Dialog wird ein Zoom-Faktor eingestellt.

    [Items]
    SvxZoomItem <SID_ATTR_ZOOM>
*/

#include <layout/layout-pre.hxx>

class SvxZoomDialog : public SfxModalDialog
{
private:
    FixedLine           aZoomFl;
    RadioButton         aOptimalBtn;
    RadioButton         aWholePageBtn;
    RadioButton         aPageWidthBtn;
    RadioButton         a100Btn;
    RadioButton         aUserBtn;
    MetricField         aUserEdit;

    FixedLine           aViewLayoutFl;
    RadioButton         aAutomaticBtn;
    RadioButton         aSingleBtn;
    RadioButton         aColumnsBtn;
    MetricField         aColumnsEdit;
    CheckBox            aBookModeChk;

    FixedLine           aBottomFl;
    OKButton            aOKBtn;
    CancelButton        aCancelBtn;
    HelpButton          aHelpBtn;

    const SfxItemSet&   rSet;
    SfxItemSet*         pOutSet;
    BOOL                bModified;

#ifdef _SVX_ZOOM_CXX
    DECL_LINK( UserHdl, RadioButton* );
    DECL_LINK( SpinHdl, MetricField* );
    DECL_LINK( ViewLayoutUserHdl, RadioButton* );
    DECL_LINK( ViewLayoutSpinHdl, MetricField* );
    DECL_LINK( ViewLayoutCheckHdl, CheckBox* );
    DECL_LINK( OKHdl, Button* );
#endif

public:
    SvxZoomDialog( Window* pParent, const SfxItemSet& rCoreSet );
    ~SvxZoomDialog();

    static USHORT*      GetRanges();
    const SfxItemSet*   GetOutputItemSet() const { return pOutSet; }

    USHORT              GetFactor() const;
    void                SetFactor( USHORT nNewFactor, USHORT nBtnId = 0 );

    void                SetButtonText( USHORT nBtnId, const String& aNewTxt );
    void                HideButton( USHORT nBtnId );
    void                SetLimits( USHORT nMin, USHORT nMax );
    void                SetSpinSize( USHORT nNewSpin );
};

#include <layout/layout-post.hxx>

#endif

<commit_msg>INTEGRATION: CWS changefileheader (1.5.50); FILE MERGED 2008/04/01 15:50:36 thb 1.5.50.2: #i85898# Stripping all external header guards 2008/03/31 14:20:10 rt 1.5.50.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: zoom.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SVX_ZOOM_HXX
#define _SVX_ZOOM_HXX

// include ---------------------------------------------------------------

#include <layout/layout.hxx>
#include <sfx2/basedlgs.hxx>
#ifndef _SV_BUTTON_HXX //autogen wg. Radio-/OK-/Cancel-/HelpButton
#include <vcl/button.hxx>
#endif
#include <vcl/field.hxx>
#include <vcl/fixed.hxx>

// define ----------------------------------------------------------------
/* CHINA001
#define ZOOMBTN_OPTIMAL     ((USHORT)0x0001)
#define ZOOMBTN_PAGEWIDTH   ((USHORT)0x0002)
#define ZOOMBTN_WHOLEPAGE   ((USHORT)0x0004)
*/
#ifndef _SVX_ZOOM_HXX
#include "zoom_def.hxx"
#endif
// class SvxZoomDialog ---------------------------------------------------
/*
    {k:\svx\prototyp\dialog\zoom.bmp}

    [Beschreibung]
    Mit diesem Dialog wird ein Zoom-Faktor eingestellt.

    [Items]
    SvxZoomItem <SID_ATTR_ZOOM>
*/

#include <layout/layout-pre.hxx>

class SvxZoomDialog : public SfxModalDialog
{
private:
    FixedLine           aZoomFl;
    RadioButton         aOptimalBtn;
    RadioButton         aWholePageBtn;
    RadioButton         aPageWidthBtn;
    RadioButton         a100Btn;
    RadioButton         aUserBtn;
    MetricField         aUserEdit;

    FixedLine           aViewLayoutFl;
    RadioButton         aAutomaticBtn;
    RadioButton         aSingleBtn;
    RadioButton         aColumnsBtn;
    MetricField         aColumnsEdit;
    CheckBox            aBookModeChk;

    FixedLine           aBottomFl;
    OKButton            aOKBtn;
    CancelButton        aCancelBtn;
    HelpButton          aHelpBtn;

    const SfxItemSet&   rSet;
    SfxItemSet*         pOutSet;
    BOOL                bModified;

#ifdef _SVX_ZOOM_CXX
    DECL_LINK( UserHdl, RadioButton* );
    DECL_LINK( SpinHdl, MetricField* );
    DECL_LINK( ViewLayoutUserHdl, RadioButton* );
    DECL_LINK( ViewLayoutSpinHdl, MetricField* );
    DECL_LINK( ViewLayoutCheckHdl, CheckBox* );
    DECL_LINK( OKHdl, Button* );
#endif

public:
    SvxZoomDialog( Window* pParent, const SfxItemSet& rCoreSet );
    ~SvxZoomDialog();

    static USHORT*      GetRanges();
    const SfxItemSet*   GetOutputItemSet() const { return pOutSet; }

    USHORT              GetFactor() const;
    void                SetFactor( USHORT nNewFactor, USHORT nBtnId = 0 );

    void                SetButtonText( USHORT nBtnId, const String& aNewTxt );
    void                HideButton( USHORT nBtnId );
    void                SetLimits( USHORT nMin, USHORT nMax );
    void                SetSpinSize( USHORT nNewSpin );
};

#include <layout/layout-post.hxx>

#endif

<|endoftext|>


<commit_before>#include <platforms/posix/stacktrace.h>

#if defined(COFFEE_UNIXPLAT)

#include <peripherals/base.h>
#include <peripherals/libc/output_ops.h>
#include <peripherals/semantic/chunk.h>
#include <peripherals/semantic/ptr_wrap.h>
#include <peripherals/stl/regex.h>
#include <peripherals/stl/string_ops.h>

#include <cxxabi.h> //Demangling function names

#if defined(COFFEE_USE_UNWIND)
#define UNW_LOCAL_ONLY
#include <libunwind.h> //For retrieving the callstack
#endif

#if defined(COFFEE_GLIBC_STACKTRACE)
#include <execinfo.h>
#endif

namespace platform {
namespace env {
namespace posix {

using namespace ::stl_types;
using namespace ::semantic;

CString Stacktracer::DemangleSymbol(const char* sym)
{
#ifndef COFFEE_LOWFAT
    i32 stat = 0;

    Ptr<char, ptr_opts::managed_ptr> symbol =
        abi::__cxa_demangle(sym, nullptr, nullptr, &stat);

    if(stat == 0)
    {
        CString outSymbol = symbol.ptr;
        return outSymbol;
    } else
#endif
        return sym;
}

StacktracerDef::Stacktrace Stacktracer::GetRawStackframes(
    C_UNUSED(u32 start), C_UNUSED(i32 length))
{
    Stacktrace t;
#ifndef COFFEE_LOWFAT
#if defined(COFFEE_USE_UNWIND)
    if(!unwind_context)
    {
        unwind_context = new unw_context_t;
        unw_getcontext(unwind_context);
    }

    unw_cursor_t cursor;
    unw_init_local(&cursor, unwind_context);

    for(uint32 i = 0; i < start; i++)
        unw_step(&cursor);

    CString temp_buf;
    temp_buf.resize(256);

    int32 depth = 0;

    while(unw_step(&cursor) > 0)
    {
        unw_word_t offset, pc;
        unw_get_reg(&cursor, UNW_REG_IP, &pc);
        if(pc == 0)
            break;
        if(unw_get_proc_name(
               &cursor,
               &temp_buf[0],
               temp_buf.size() * sizeof(char),
               &offset) == 0)
        {
            CString fname = DemangleSymbol(temp_buf);
            t.push_back(fname);
        }

        depth++;
        if(length != (-1) && depth == length)
            break;
    }
#endif
#endif
    return t;
}

CString Stacktracer::GetStackframeName(u32 depth)
{
#ifndef COFFEE_LOWFAT
    Stacktrace trace = GetRawStackframes(depth, 2);
    if(!trace.size())
        return "???";
    return CString(trace[0]);
#else
    return {};
#endif
}

CString Stacktracer::GetStackFuncName(u32 depth)
{
#ifndef COFFEE_LOWFAT
    static bool           rgx_compiled;
    static regex::Pattern rgx;

    CString frame = GetStackframeName(depth + 1);

    if(!rgx_compiled)
    {
        rgx = regex::compile_pattern("^(.*)\\(.*$");
    }

    Vector<CString> result;

    if(!regex::match(rgx, frame, result))
        return frame;

    return result[1];
#else
    return {};
#endif
}

} // namespace posix

#if defined(COFFEE_GLIBC_STACKTRACE)
namespace glibc {

STATICINLINE CString DemangleBacktrace(char* sym)
{
    CString sym_ = sym;
#if defined(COFFEE_LINUX) || defined(COFFEE_APPLE)
    /* glibc's format */
    auto sym_end = sym_.rfind('+');

#if defined(COFFEE_APPLE)
    /* macOS format looks like this:
     * 0   GLeamBaseTest_RHI                   0x000000010030c86a SIGNATURE + 0
     *                                  What we want    ~~~~~~~~~^
     * We fix this by adjusting the beginning index
     */
    auto sym_begin = sym_.rfind(' ', sym_end);
    sym_begin      = sym_.rfind(' ', sym_begin - 1);

    sym_end -= 1;
#else
    auto sym_begin = sym_.rfind('(', sym_end);
#endif

    if(sym_end != CString::npos && sym_begin != CString::npos)
    {
        auto sym_length = sym_end - sym_begin - 1;
        auto sym_target = sym_.substr(sym_begin + 1, sym_length);

        sym_ = str::replace::str(
            sym_, sym_target, Stacktracer::DemangleSymbol(sym_target));
    }
#endif

#if defined(COFFEE_APPLE)
    auto const is_space = [](CString::value_type v) {
        return !std::isspace(v);
    };

    auto crop = sym_.find(' ');

    auto crop_it = std::find_if(sym_.begin() + crop, sym_.end(), is_space);

    auto cursor_start = crop_it - sym_.begin();
    auto cursor_end = sym_.find(' ', cursor_start);

    auto module = sym_.substr(cursor_start, cursor_end - cursor_start);

    crop_it = std::find_if(sym_.begin() + cursor_end, sym_.end(), is_space);
    cursor_start = crop_it - sym_.begin();
    cursor_end = sym_.find(' ', cursor_start);

    auto address = sym_.substr(cursor_start, cursor_end - cursor_start);

    crop_it = std::find_if(sym_.begin() + cursor_end, sym_.end(), is_space);
    cursor_start = crop_it - sym_.begin();
    cursor_end = sym_.find(' ', cursor_start);

    auto func = sym_.substr(cursor_start, CString::npos);

    return module + "(" + func + ") [" + address + "]";
#else
    return sym_;
#endif
}

static void DefaultedPrint(
    typing::logging::LogInterfaceBasic logger, CString const& line)
{
    using semantic::debug::Severity;
    using namespace libc::io;

    logger(io_handles::err, line, Severity::Critical, 1, 0);
}

void Stacktracer::Backtrace(typing::logging::LogInterfaceBasic log)
{
    static constexpr szptr MAX_CONTEXT = 21;
    static void* tracestore[MAX_CONTEXT];

    for(szptr i=0; i<MAX_CONTEXT; i++)
        tracestore[i] = nullptr;

    auto num  = backtrace(tracestore, MAX_CONTEXT);

    if(!log)
    {
        backtrace_symbols(tracestore, num);
        return;
    }

    auto syms = backtrace_symbols(tracestore, num);
    if(syms && num)
    {
        DefaultedPrint(log, "dumping stacktrace:");
        for(auto i : Range<>(C_FCAST<szptr>(num)))
        {
            if(syms[i])
            {
                DefaultedPrint(log, " >> " + DemangleBacktrace(syms[i]));
            } else
                DefaultedPrint(
                    log, " >> " + Stacktracer::DemangleSymbol(syms[i]));
        }
    }
}

void Stacktracer::ExceptionStacktrace(
    const ExceptionPtr& exc_ptr, typing::logging::LogInterfaceBasic log)
{
    try
    {
        if(exc_ptr)
            std::rethrow_exception(exc_ptr);
    } catch(std::exception& e)
    {
        if(libc::io::terminal::interactive())
            DefaultedPrint(
                log,
                str::transform::multiply(
                    '-', libc::io::terminal::size().first));
        DefaultedPrint(log, "exception encountered:");
        DefaultedPrint(
            log,
            " >> " + Stacktracer::DemangleSymbol(typeid(e).name()) + ": " +
                e.what());
        Backtrace(log);
    }
}

CString Stacktracer::GetFuncName_Internal(void* funcPtr)
{
    auto funcName = backtrace_symbols(&funcPtr, 1);

    if(!funcName)
        return {};

    CString out = DemangleBacktrace(funcName[0]);
    free(funcName);

    return out;
}

} // namespace glibc
#endif

} // namespace env
} // namespace platform

#endif
<commit_msg> - Free backtrace memory on exit<commit_after>#include <platforms/posix/stacktrace.h>

#if defined(COFFEE_UNIXPLAT)

#include <peripherals/base.h>
#include <peripherals/libc/output_ops.h>
#include <peripherals/semantic/chunk.h>
#include <peripherals/semantic/ptr_wrap.h>
#include <peripherals/stl/regex.h>
#include <peripherals/stl/string_ops.h>

#include <cxxabi.h> //Demangling function names

#if defined(COFFEE_USE_UNWIND)
#define UNW_LOCAL_ONLY
#include <libunwind.h> //For retrieving the callstack
#endif

#if defined(COFFEE_GLIBC_STACKTRACE)
#include <execinfo.h>
#include <peripherals/libc/signals.h>
#endif

namespace platform {
namespace env {
namespace posix {

using namespace ::stl_types;
using namespace ::semantic;

CString Stacktracer::DemangleSymbol(const char* sym)
{
#ifndef COFFEE_LOWFAT
    i32 stat = 0;

    Ptr<char, ptr_opts::managed_ptr> symbol =
        abi::__cxa_demangle(sym, nullptr, nullptr, &stat);

    if(stat == 0)
    {
        CString outSymbol = symbol.ptr;
        return outSymbol;
    } else
#endif
        return sym;
}

StacktracerDef::Stacktrace Stacktracer::GetRawStackframes(
    C_UNUSED(u32 start), C_UNUSED(i32 length))
{
    Stacktrace t;
#ifndef COFFEE_LOWFAT
#if defined(COFFEE_USE_UNWIND)
    if(!unwind_context)
    {
        unwind_context = new unw_context_t;
        unw_getcontext(unwind_context);
    }

    unw_cursor_t cursor;
    unw_init_local(&cursor, unwind_context);

    for(uint32 i = 0; i < start; i++)
        unw_step(&cursor);

    CString temp_buf;
    temp_buf.resize(256);

    int32 depth = 0;

    while(unw_step(&cursor) > 0)
    {
        unw_word_t offset, pc;
        unw_get_reg(&cursor, UNW_REG_IP, &pc);
        if(pc == 0)
            break;
        if(unw_get_proc_name(
               &cursor,
               &temp_buf[0],
               temp_buf.size() * sizeof(char),
               &offset) == 0)
        {
            CString fname = DemangleSymbol(temp_buf);
            t.push_back(fname);
        }

        depth++;
        if(length != (-1) && depth == length)
            break;
    }
#endif
#endif
    return t;
}

CString Stacktracer::GetStackframeName(u32 depth)
{
#ifndef COFFEE_LOWFAT
    Stacktrace trace = GetRawStackframes(depth, 2);
    if(!trace.size())
        return "???";
    return CString(trace[0]);
#else
    return {};
#endif
}

CString Stacktracer::GetStackFuncName(u32 depth)
{
#ifndef COFFEE_LOWFAT
    static bool           rgx_compiled;
    static regex::Pattern rgx;

    CString frame = GetStackframeName(depth + 1);

    if(!rgx_compiled)
    {
        rgx = regex::compile_pattern("^(.*)\\(.*$");
    }

    Vector<CString> result;

    if(!regex::match(rgx, frame, result))
        return frame;

    return result[1];
#else
    return {};
#endif
}

} // namespace posix

#if defined(COFFEE_GLIBC_STACKTRACE)
namespace glibc {

STATICINLINE CString DemangleBacktrace(char* sym)
{
    CString sym_ = sym;
#if defined(COFFEE_LINUX) || defined(COFFEE_APPLE)
    /* glibc's format */
    auto sym_end = sym_.rfind('+');

#if defined(COFFEE_APPLE)
    /* macOS format looks like this:
     * 0   GLeamBaseTest_RHI                   0x000000010030c86a SIGNATURE + 0
     *                                  What we want    ~~~~~~~~~^
     * We fix this by adjusting the beginning index
     */
    auto sym_begin = sym_.rfind(' ', sym_end);
    sym_begin      = sym_.rfind(' ', sym_begin - 1);

    sym_end -= 1;
#else
    auto sym_begin = sym_.rfind('(', sym_end);
#endif

    if(sym_end != CString::npos && sym_begin != CString::npos)
    {
        auto sym_length = sym_end - sym_begin - 1;
        auto sym_target = sym_.substr(sym_begin + 1, sym_length);

        sym_ = str::replace::str(
            sym_, sym_target, Stacktracer::DemangleSymbol(sym_target));
    }
#endif

#if defined(COFFEE_APPLE)
    auto const is_space = [](CString::value_type v) {
        return !std::isspace(v);
    };

    auto crop = sym_.find(' ');

    auto crop_it = std::find_if(sym_.begin() + crop, sym_.end(), is_space);

    auto cursor_start = crop_it - sym_.begin();
    auto cursor_end = sym_.find(' ', cursor_start);

    auto module = sym_.substr(cursor_start, cursor_end - cursor_start);

    crop_it = std::find_if(sym_.begin() + cursor_end, sym_.end(), is_space);
    cursor_start = crop_it - sym_.begin();
    cursor_end = sym_.find(' ', cursor_start);

    auto address = sym_.substr(cursor_start, cursor_end - cursor_start);

    crop_it = std::find_if(sym_.begin() + cursor_end, sym_.end(), is_space);
    cursor_start = crop_it - sym_.begin();
    cursor_end = sym_.find(' ', cursor_start);

    auto func = sym_.substr(cursor_start, CString::npos);

    return module + "(" + func + ") [" + address + "]";
#else
    return sym_;
#endif
}

static void DefaultedPrint(
    typing::logging::LogInterfaceBasic logger, CString const& line)
{
    using semantic::debug::Severity;
    using namespace libc::io;

    logger(io_handles::err, line, Severity::Critical, 1, 0);
}

COFFEE_DISABLE_ASAN void Stacktracer::Backtrace(typing::logging::LogInterfaceBasic log)
{
    static constexpr szptr MAX_CONTEXT = 21;
    static void* tracestore[MAX_CONTEXT];

    for(szptr i=0; i<MAX_CONTEXT; i++)
        tracestore[i] = nullptr;

    auto num = backtrace(tracestore, MAX_CONTEXT);

    if(!log)
    {
        backtrace_symbols(tracestore, num);
        libc::signal::register_atexit([]()
        {
            ::free(backtrace_symbols(tracestore, MAX_CONTEXT));
        });
        return;
    }

    auto syms = backtrace_symbols(tracestore, num);
    if(syms && num)
    {
        DefaultedPrint(log, "dumping stacktrace:");
        for(auto i : Range<>(C_FCAST<szptr>(num)))
        {
            if(syms[i])
            {
                DefaultedPrint(log, " >> " + DemangleBacktrace(syms[i]));
            } else
                DefaultedPrint(
                    log, " >> " + Stacktracer::DemangleSymbol(syms[i]));
        }
    }
}

void Stacktracer::ExceptionStacktrace(
    const ExceptionPtr& exc_ptr, typing::logging::LogInterfaceBasic log)
{
    try
    {
        if(exc_ptr)
            std::rethrow_exception(exc_ptr);
    } catch(std::exception& e)
    {
        if(libc::io::terminal::interactive())
            DefaultedPrint(
                log,
                str::transform::multiply(
                    '-', libc::io::terminal::size().first));
        DefaultedPrint(log, "exception encountered:");
        DefaultedPrint(
            log,
            " >> " + Stacktracer::DemangleSymbol(typeid(e).name()) + ": " +
                e.what());
        Backtrace(log);
    }
}

CString Stacktracer::GetFuncName_Internal(void* funcPtr)
{
    auto funcName = backtrace_symbols(&funcPtr, 1);

    if(!funcName)
        return {};

    CString out = DemangleBacktrace(funcName[0]);
    free(funcName);

    return out;
}

} // namespace glibc
#endif

} // namespace env
} // namespace platform

#endif
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <stan/math/prim.hpp>
#include <vector>

TEST(MathPrimScalFun, grad2F1_negative_z) {
  double a1 = 3.70975;
  double a2 = 1;
  double b1 = 2.70975;
  double z = -0.2;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(-0.0488658806159776, grad_a1, 1e-9);
  EXPECT_NEAR(-0.193844936204681, grad_a2, 1e-9);
  EXPECT_NEAR(0.0677809985598383, grad_b1, 1e-9);
}

TEST(MathPrimScalFun, grad2F1_zero_z) {
  double a1 = 3.70975;
  double a2 = 1;
  double b1 = 2.70975;
  double z = 0;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_FLOAT_EQ(0, grad_a1);
  EXPECT_FLOAT_EQ(0, grad_a2);
  EXPECT_FLOAT_EQ(0, grad_b1);
}

TEST(MathPrimScalFun, grad2F1_1) {
  double a1 = 1;
  double a2 = 1;
  double b1 = 1;
  double z = 0.6;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(2.290726829685388, grad_a1, 1e-9);
  EXPECT_NEAR(2.290726829685388, grad_a2, 1e-9);
  EXPECT_NEAR(-2.290726829685388, grad_b1, 1e-9);
}

TEST(MathPrimScalFun, grad2F1_2) {
  double a1 = 1;
  double a2 = 31;
  double b1 = 41;
  double z = 1;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z, 1e-11);
  EXPECT_NEAR(6.825270649241036, grad_a1, 1e-8);
  EXPECT_NEAR(0.4938271604938271, grad_a2, 1e-8);
  EXPECT_NEAR(-0.382716049382716, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_3) {
  double a1 = 1;
  double a2 = -2.1;
  double b1 = 41;
  double z = 1;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(-0.04921317604093563, grad_a1, 1e-8);
  EXPECT_NEAR(0.02256814168279349, grad_a2, 1e-8);
  EXPECT_NEAR(0.00118482743834665, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_4) {
  double a1 = 1;
  double a2 = 12;
  double b1 = 10;
  double z = 1;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  EXPECT_THROW(stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z),
               std::domain_error);
}

TEST(MathPrimScalFun, grad2F1_5) {
  double a1 = 1;
  double a2 = 12;
  double b1 = 20;
  double z = 1.2;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  EXPECT_THROW(stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z),
               std::domain_error);
}

TEST(MathPrimScalFun, grad2F1_6) {
  double a1 = 1;
  double a2 = -0.5;
  double b1 = 10.6;
  double z = 0.3;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(-0.01443822031245647, grad_a1, 1e-8);
  EXPECT_NEAR(0.02829710651967078, grad_a2, 1e-8);
  EXPECT_NEAR(0.00136986255602642, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_7) {
  double a1 = 1;
  double a2 = -0.5;
  double b1 = 10;
  double z = 0.3;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(-0.0153218866216130, grad_a1, 1e-8);
  EXPECT_NEAR(0.02999436412836072, grad_a2, 1e-8);
  EXPECT_NEAR(0.0015413242328729, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_8) {
  double a1 = -.5;
  double a2 = -4.5;
  double b1 = 11;
  double z = 0.3;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(-0.1227022810085707, grad_a1, 1e-8);
  EXPECT_NEAR(-0.01298849638043795, grad_a2, 1e-8);
  EXPECT_NEAR(-0.0053540982315572, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_9) {
  double a1 = -.5;
  double a2 = -4.5;
  double b1 = -3.2;
  double z = 0.9;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(0.85880025358111, grad_a1, 1e-8);
  EXPECT_NEAR(0.4677704416159314, grad_a2, 1e-8);
  EXPECT_NEAR(-4.19010422485256, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_10) {
  double a1 = 2;
  double a2 = 1;
  double b1 = 2;
  double z = 0.4;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);
  EXPECT_NEAR(0.4617734323582945, grad_a1, 1e-8);
  EXPECT_NEAR(0.851376039609984, grad_a2, 1e-8);
  EXPECT_NEAR(-0.4617734323582945, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_11) {
  double a1 = 3.70975;
  double a2 = 1;
  double b1 = 2.70975;
  double z = 0.999696;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, a1, a2, b1, z);

  EXPECT_NEAR(29369830.002773938200417693317785, grad_a1,
              1e-1);  // reference: discrete diff in mathematica
  EXPECT_NEAR(36347869.41885337, grad_a2, 1e-1);
  EXPECT_NEAR(-30843032.10697079073015067426929807, grad_b1,
              1e-1);  // reference: discrete diff in mathematica
}
<commit_msg>Update prim tests<commit_after>#include <gtest/gtest.h>
#include <stan/math/prim.hpp>
#include <vector>

TEST(MathPrimScalFun, grad2F1_negative_z) {
  double a1 = 3.70975;
  double a2 = 1;
  double b1 = 2.70975;
  double z = -0.2;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(-0.0488658806159776, grad_a1, 1e-9);
  EXPECT_NEAR(-0.193844936204681, grad_a2, 1e-9);
  EXPECT_NEAR(0.0677809985598383, grad_b1, 1e-9);
}

TEST(MathPrimScalFun, grad2F1_zero_z) {
  double a1 = 3.70975;
  double a2 = 1;
  double b1 = 2.70975;
  double z = 0;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_FLOAT_EQ(0, grad_a1);
  EXPECT_FLOAT_EQ(0, grad_a2);
  EXPECT_FLOAT_EQ(0, grad_b1);
}

TEST(MathPrimScalFun, grad2F1_1) {
  double a1 = 1;
  double a2 = 1;
  double b1 = 1;
  double z = 0.6;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(2.290726829685388, grad_a1, 1e-9);
  EXPECT_NEAR(2.290726829685388, grad_a2, 1e-9);
  EXPECT_NEAR(-2.290726829685388, grad_b1, 1e-9);
}

TEST(MathPrimScalFun, grad2F1_2) {
  double a1 = 1;
  double a2 = 31;
  double b1 = 41;
  double z = 1;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(6.825270649241036, grad_a1, 1e-8);
  EXPECT_NEAR(0.4938271604938271, grad_a2, 1e-8);
  EXPECT_NEAR(-0.382716049382716, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_3) {
  double a1 = 1;
  double a2 = -2.1;
  double b1 = 41;
  double z = 1;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(-0.04921317604093563, grad_a1, 1e-8);
  EXPECT_NEAR(0.02256814168279349, grad_a2, 1e-8);
  EXPECT_NEAR(0.00118482743834665, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_4) {
  double a1 = 1;
  double a2 = 12;
  double b1 = 10;
  double z = 1;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  EXPECT_THROW(
    stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z),
    std::domain_error);
}

TEST(MathPrimScalFun, grad2F1_5) {
  double a1 = 1;
  double a2 = 12;
  double b1 = 20;
  double z = 1.2;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  EXPECT_THROW(
    stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z),
    std::domain_error);
}

TEST(MathPrimScalFun, grad2F1_6) {
  double a1 = 1;
  double a2 = -0.5;
  double b1 = 10.6;
  double z = 0.3;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(-0.01443822031245647, grad_a1, 1e-8);
  EXPECT_NEAR(0.02829710651967078, grad_a2, 1e-8);
  EXPECT_NEAR(0.00136986255602642, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_7) {
  double a1 = 1;
  double a2 = -0.5;
  double b1 = 10;
  double z = 0.3;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(-0.0153218866216130, grad_a1, 1e-8);
  EXPECT_NEAR(0.02999436412836072, grad_a2, 1e-8);
  EXPECT_NEAR(0.0015413242328729, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_8) {
  double a1 = -.5;
  double a2 = -4.5;
  double b1 = 11;
  double z = 0.3;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(-0.1227022810085707, grad_a1, 1e-8);
  EXPECT_NEAR(-0.01298849638043795, grad_a2, 1e-8);
  EXPECT_NEAR(-0.0053540982315572, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_9) {
  double a1 = -.5;
  double a2 = -4.5;
  double b1 = -3.2;
  double z = 0.9;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(0.85880025358111, grad_a1, 1e-8);
  EXPECT_NEAR(0.4677704416159314, grad_a2, 1e-8);
  EXPECT_NEAR(-4.19010422485256, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_10) {
  double a1 = 2;
  double a2 = 1;
  double b1 = 2;
  double z = 0.4;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);
  EXPECT_NEAR(0.4617734323582945, grad_a1, 1e-8);
  EXPECT_NEAR(0.851376039609984, grad_a2, 1e-8);
  EXPECT_NEAR(-0.4617734323582945, grad_b1, 1e-8);
}

TEST(MathPrimScalFun, grad2F1_11) {
  double a1 = 3.70975;
  double a2 = 1;
  double b1 = 2.70975;
  double z = 0.999696;

  double grad_a1;
  double grad_a2;
  double grad_b1;
  double grad_z;
  stan::math::grad_2F1(grad_a1, grad_a2, grad_b1, grad_z, a1, a2, b1, z);

  EXPECT_NEAR(29369830.002773938200417693317785, grad_a1,
              1e-1);  // reference: discrete diff in mathematica
  EXPECT_NEAR(36347869.41885337, grad_a2, 1e-1);
  EXPECT_NEAR(-30843032.10697079073015067426929807, grad_b1,
              1e-1);  // reference: discrete diff in mathematica
}
<|endoftext|>