<commit_before>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptProblem.cpp,v $
   $Revision: 1.60 $
   $Name:  $
   $Author: ssahle $
   $Date: 2005/08/03 22:39:07 $
   End CVS Header */

/**
 *  File name: COptProblem.cpp
 *
 *  Programmer: Yongqun He
 *  Contact email: yohe@vt.edu
 *  Purpose: This is the source file of the COptProblem class.
 *           It specifies the optimization problem with its own members and
 *           functions. It's used by COptAlgorithm class and COptimization class
 */
#include <float.h>

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

#include "function/CFunctionDB.h"

#include "CopasiDataModel/CCopasiDataModel.h"

#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "trajectory/CTrajectoryProblem.h"

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

#include "report/CCopasiObjectReference.h"
#include "report/CKeyFactory.h"

#include "utilities/CProcessReport.h"

//  Default constructor
COptProblem::COptProblem(const CCopasiContainer * pParent):
    CCopasiProblem(CCopasiTask::optimization, pParent),
    mpSteadyState(NULL),
    mpTrajectory(NULL),
    mpFunction(NULL),
    mOptItemList()
{
  addGroup("OptimizationItemList");
  addGroup("OptimizationConstraintList");

  addParameter("Steady-State", CCopasiParameter::KEY, (std::string) "");
  addParameter("Time-Course", CCopasiParameter::KEY, (std::string) "");
  addParameter("ObjectiveFunction", CCopasiParameter::KEY, (std::string) "");
  addParameter("Maximize", CCopasiParameter::BOOL, (bool) false);

  initObjects();
}

// copy constructor
COptProblem::COptProblem(const COptProblem& src,
                         const CCopasiContainer * pParent):
    CCopasiProblem(src, pParent),
    mpSteadyState(src.mpSteadyState),
    mpTrajectory(src.mpTrajectory),
    mpFunction(NULL),
    mOptItemList()
{
  if (src.mpFunction)
    {
      createObjectiveFunction();
      mpFunction->setInfix(src.mpFunction->getInfix());
      setValue("ObjectiveFunction", mpFunction->getKey());
    }

  initObjects();
}

// Destructor
COptProblem::~COptProblem()
{
  std::vector<COptItem *>::iterator it = mOptItemList.begin();
  std::vector<COptItem *>::iterator end = mOptItemList.end();

  for (; it != end; ++it)
    pdelete(*it);

  if (mpFunction && CCopasiDataModel::Global && CCopasiDataModel::Global->getFunctionList())
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions().remove(mpFunction->getObjectName());

  pdelete(mpFunction);
}

bool COptProblem::setModel(CModel * pModel)
{
  mpModel = pModel;
  return true;
}

bool COptProblem::setCallBack(CProcessReport * pCallBack)
{
  CCopasiProblem::setCallBack(pCallBack);

  if (pCallBack)
    {
      mhSolutionValue =
        mpCallBack->addItem("Best Value",
                            CCopasiParameter::DOUBLE,
                            & mSolutionValue);
      mhCounter =
        mpCallBack->addItem("Simulation Counter",
                            CCopasiParameter::UINT,
                            & mCounter);
    }

  return true;
}

void COptProblem::initObjects()
{
  addObjectReference("Simulation Counter", mCounter, CCopasiObject::ValueInt);
  addObjectReference("Best Value", mSolutionValue, CCopasiObject::ValueDbl);
  addVectorReference("Best Parameters", mSolutionVariables, CCopasiObject::ValueDbl);
}

#ifdef WIN32
// warning C4056: overflow in floating-point constant arithmetic
// warning C4756: overflow in constant arithmetic
# pragma warning (disable: 4056 4756)
#endif

bool COptProblem::initialize()
{
  if (!mpModel) return false;
  mpModel->compileIfNecessary();

  mpReport = NULL;
  mCounter = 0;
  mSolutionValue = DBL_MAX * 2;

  std::vector< CCopasiContainer * > ContainerList;
  ContainerList.push_back(mpModel);

  COptTask * pTask = dynamic_cast<COptTask *>(getObjectParent());
  if (pTask)
    {
      ContainerList.push_back(pTask);
      mpReport = &pTask->getReport();
      if (!mpReport->getStream()) mpReport = NULL;
    }

  mpSteadyState =
    dynamic_cast<CSteadyStateTask *>(GlobalKeys.get(* getValue("Steady-State").pKEY));
  mpTrajectory =
    dynamic_cast<CTrajectoryTask *>(GlobalKeys.get(* getValue("Time-Course").pKEY));

  if (!mpSteadyState && !mpTrajectory) return false;

  if (mpSteadyState)
    {
      mpSteadyState->initialize();
      ContainerList.push_back(mpSteadyState);
    }
  if (mpTrajectory)
    {
      mpTrajectory->initialize();
      ContainerList.push_back(mpTrajectory);
    }

  buildOptItemListFromParameterGroup();

  unsigned C_INT32 i;
  unsigned C_INT32 Size = mOptItemList.size();

  mUpdateMethods.resize(Size);
  mSolutionVariables.resize(Size);
  mOriginalVariables.resize(Size);

  std::vector< COptItem * >::iterator it = mOptItemList.begin();
  std::vector< COptItem * >::iterator end = mOptItemList.end();

  for (i = 0; it != end; ++it, i++)
    {
      if (!(*it)->compile(ContainerList)) return false;
      mUpdateMethods[i] = (*it)->getUpdateMethod();
      mOriginalVariables[i] = *(*it)->getObjectValue();
    }

  createObjectiveFunction();
  if (!mpFunction) return false;

  return mpFunction->compile(ContainerList);
}

bool COptProblem::restore()
{
  unsigned C_INT32 i, imax = mOptItemList.size();

  // set the original paramter values
  for (i = 0; i < imax; i++)
    (*mUpdateMethods[i])(mOriginalVariables[i]);

  return true;
}

#ifdef WIN32
# pragma warning (default: 4056 4756)
#endif

bool COptProblem::checkParametricConstraints()
{
  std::vector< COptItem * >::const_iterator it = mOptItemList.begin();
  std::vector< COptItem * >::const_iterator end = mOptItemList.end();

  for (; it != end; ++it)
    if ((*it)->checkConstraint()) return false;

  return true;
}

bool COptProblem::checkFunctionalConstraints()
{
  return true; // :TODO:
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool COptProblem::calculate()
{
  mCounter += 1;

  try
    {
      if (mpSteadyState != NULL)
        {
          //((CSteadyStateProblem *) mpSteadyState->getProblem())->
          //setInitialState(mpSteadyState->getProblem()->getModel()->getInitialState());
          mpSteadyState->process();
        }

      if (mpTrajectory != NULL)
        {
          //((CTrajectoryProblem *) mpTrajectory->getProblem())->
          //setInitialState(mpTrajectory->getProblem()->getModel()->getInitialState());
          mpTrajectory->process(CCopasiTask::NO_OUTPUT);
        }

      mCalculateValue = mpFunction->calcValue();
    }

  catch (...)
    {
      mCalculateValue = DBL_MAX;
    }

  if (mpCallBack) return mpCallBack->progress(mhCounter);

  return true;
}

const C_FLOAT64 & COptProblem::getCalculateValue() const
{return mCalculateValue;}

void COptProblem::setSolutionVariables(const CVector< C_FLOAT64 > & variables)
{mSolutionVariables = variables;}

const CVector< C_FLOAT64 > & COptProblem::getSolutionVariables() const
  {return mSolutionVariables;}

bool COptProblem::setSolutionValue(const C_FLOAT64 & value)
{
  mSolutionValue = value;
  if (mpCallBack) return mpCallBack->progress(mhSolutionValue);

  return true;
}

const C_FLOAT64 & COptProblem::getSolutionValue() const
{return mSolutionValue;}

// set the type of problem : Steady State OR Trajectory
void COptProblem::setProblemType(ProblemType type)
{
  // :TODO:
  if (type == SteadyState)
    mpSteadyState = new CSteadyStateTask(/*this*/NULL);
  if (type == Trajectory)
    mpTrajectory = new CTrajectoryTask(/*this*/NULL);
}

COptItem & COptProblem::getOptItem(const unsigned C_INT32 & index)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  assert(index < mOptItemList.size());

  return *mOptItemList[index];
}

const unsigned C_INT32 COptProblem::getOptItemSize() const
{return getValue("OptimizationItemList").pGROUP->size();}

COptItem & COptProblem::addOptItem(const CCopasiObjectName & objectCN)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  unsigned C_INT32 index = getOptItemSize();

  CCopasiParameterGroup * pOptimizationItemList = (CCopasiParameterGroup *) getParameter("OptimizationItemList");

  pOptimizationItemList->addGroup("OptimizationItem");

  CCopasiParameterGroup * pOptItem =
    (CCopasiParameterGroup *) pOptimizationItemList->getParameter(index);

  assert(pOptItem != NULL);

  COptItem * pTmp = new COptItem(*pOptItem);

  //pTmp->setLowerBound(

  if (!pTmp->initialize(objectCN)) fatalError();

  mOptItemList.push_back(pTmp);

  return *pTmp;
}

bool COptProblem::removeOptItem(const unsigned C_INT32 & index)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  if (!(index < mOptItemList.size())) return false;

  pdelete(mOptItemList[index]);
  mOptItemList.erase(mOptItemList.begin() + index);

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->removeParameter(index);
}

bool COptProblem::swapOptItem(const unsigned C_INT32 & iFrom,
                              const unsigned C_INT32 & iTo)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  if (!(iFrom < mOptItemList.size()) ||
      !(iTo < mOptItemList.size()))
    return false;

  COptItem * pTmp = mOptItemList[iFrom];
  mOptItemList[iFrom] = mOptItemList[iTo];
  mOptItemList[iTo] = pTmp;

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->swap(iFrom, iTo);
}

const std::vector< COptItem * > & COptProblem::getOptItemList() const
  {
    if (mOptItemList.size() != getOptItemSize())
      const_cast<COptProblem *>(this)->buildOptItemListFromParameterGroup();

    return mOptItemList;
  }

const std::vector< UpdateMethod * > & COptProblem::getCalculateVariableUpdateMethods() const
{return mUpdateMethods;}

bool COptProblem::setObjectiveFunction(const std::string & infix)
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->setInfix(infix);
}

const std::string COptProblem::getObjectiveFunction()
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->getInfix();
}

bool COptProblem::createObjectiveFunction()
{
  mpFunction =
    dynamic_cast<CExpression *>(GlobalKeys.get(* getValue("ObjectiveFunction").pKEY));

  CCopasiVectorN<CEvaluationTree> & FunctionList =
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions();

  if (!mpFunction)
    {
      std::ostringstream Name;
      Name << "Objective Function";

      int i = 0;

      while (FunctionList.getIndex(Name.str()) != C_INVALID_INDEX)
        {
          i++;
          Name.str("");
          Name << "Objective Function " << i;
        }

      mpFunction = new CExpression(Name.str(), this);
      FunctionList.add(mpFunction, false);

      setValue("ObjectiveFunction", mpFunction->getKey());
    }
  else
    {
      mpFunction->setObjectParent(this);

      if (FunctionList.getIndex(mpFunction->getObjectName()) == C_INVALID_INDEX)
        FunctionList.add(mpFunction, false);
    }

  return true;
}

bool COptProblem::buildOptItemListFromParameterGroup()
{
  bool success = true;

  std::vector< COptItem * >::iterator it = mOptItemList.begin();
  std::vector< COptItem * >::iterator end = mOptItemList.end();

  for (; it != end; ++it)
    pdelete(*it);

  unsigned i, imax = getOptItemSize();
  mOptItemList.resize(imax);

  std::vector<CCopasiParameter *> & List = *getValue("OptimizationItemList").pGROUP;

  for (i = 0; i < imax; i++)
    {
      mOptItemList[i] = new COptItem(* (CCopasiParameterGroup *) List[i]);
      if (!mOptItemList[i]->isValid()) success = false;
    }

  return true;
}
<commit_msg>Fixed destructor's handling of the objective function.<commit_after>/* Begin CVS Header
   $Source: /Volumes/Home/Users/shoops/cvs/copasi_dev/copasi/optimization/COptProblem.cpp,v $
   $Revision: 1.61 $
   $Name:  $
   $Author: shoops $
   $Date: 2005/08/12 18:54:25 $
   End CVS Header */

/**
 *  File name: COptProblem.cpp
 *
 *  Programmer: Yongqun He
 *  Contact email: yohe@vt.edu
 *  Purpose: This is the source file of the COptProblem class.
 *           It specifies the optimization problem with its own members and
 *           functions. It's used by COptAlgorithm class and COptimization class
 */
#include <float.h>

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

#include "function/CFunctionDB.h"

#include "CopasiDataModel/CCopasiDataModel.h"

#include "steadystate/CSteadyStateTask.h"
#include "trajectory/CTrajectoryTask.h"
#include "steadystate/CSteadyStateProblem.h"
#include "trajectory/CTrajectoryProblem.h"

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

#include "report/CCopasiObjectReference.h"
#include "report/CKeyFactory.h"

#include "utilities/CProcessReport.h"

//  Default constructor
COptProblem::COptProblem(const CCopasiContainer * pParent):
    CCopasiProblem(CCopasiTask::optimization, pParent),
    mpSteadyState(NULL),
    mpTrajectory(NULL),
    mpFunction(NULL),
    mOptItemList()
{
  addGroup("OptimizationItemList");
  addGroup("OptimizationConstraintList");

  addParameter("Steady-State", CCopasiParameter::KEY, (std::string) "");
  addParameter("Time-Course", CCopasiParameter::KEY, (std::string) "");
  addParameter("ObjectiveFunction", CCopasiParameter::KEY, (std::string) "");
  addParameter("Maximize", CCopasiParameter::BOOL, (bool) false);

  initObjects();
}

// copy constructor
COptProblem::COptProblem(const COptProblem& src,
                         const CCopasiContainer * pParent):
    CCopasiProblem(src, pParent),
    mpSteadyState(src.mpSteadyState),
    mpTrajectory(src.mpTrajectory),
    mpFunction(NULL),
    mOptItemList()
{
  if (src.mpFunction)
    {
      createObjectiveFunction();
      mpFunction->setInfix(src.mpFunction->getInfix());
      setValue("ObjectiveFunction", mpFunction->getKey());
    }

  initObjects();
}

// Destructor
COptProblem::~COptProblem()
{
  std::vector<COptItem *>::iterator it = mOptItemList.begin();
  std::vector<COptItem *>::iterator end = mOptItemList.end();

  for (; it != end; ++it)
    pdelete(*it);

  if (mpFunction && CCopasiDataModel::Global &&
      CCopasiDataModel::Global->getFunctionList() &&
      CCopasiDataModel::Global->getFunctionList()->loadedFunctions()[mpFunction->getObjectName()] == mpFunction)
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions().remove(mpFunction->getObjectName());

  pdelete(mpFunction);
}

bool COptProblem::setModel(CModel * pModel)
{
  mpModel = pModel;
  return true;
}

bool COptProblem::setCallBack(CProcessReport * pCallBack)
{
  CCopasiProblem::setCallBack(pCallBack);

  if (pCallBack)
    {
      mhSolutionValue =
        mpCallBack->addItem("Best Value",
                            CCopasiParameter::DOUBLE,
                            & mSolutionValue);
      mhCounter =
        mpCallBack->addItem("Simulation Counter",
                            CCopasiParameter::UINT,
                            & mCounter);
    }

  return true;
}

void COptProblem::initObjects()
{
  addObjectReference("Simulation Counter", mCounter, CCopasiObject::ValueInt);
  addObjectReference("Best Value", mSolutionValue, CCopasiObject::ValueDbl);
  addVectorReference("Best Parameters", mSolutionVariables, CCopasiObject::ValueDbl);
}

#ifdef WIN32
// warning C4056: overflow in floating-point constant arithmetic
// warning C4756: overflow in constant arithmetic
# pragma warning (disable: 4056 4756)
#endif

bool COptProblem::initialize()
{
  if (!mpModel) return false;
  mpModel->compileIfNecessary();

  mpReport = NULL;
  mCounter = 0;
  mSolutionValue = DBL_MAX * 2;

  std::vector< CCopasiContainer * > ContainerList;
  ContainerList.push_back(mpModel);

  COptTask * pTask = dynamic_cast<COptTask *>(getObjectParent());
  if (pTask)
    {
      ContainerList.push_back(pTask);
      mpReport = &pTask->getReport();
      if (!mpReport->getStream()) mpReport = NULL;
    }

  mpSteadyState =
    dynamic_cast<CSteadyStateTask *>(GlobalKeys.get(* getValue("Steady-State").pKEY));
  mpTrajectory =
    dynamic_cast<CTrajectoryTask *>(GlobalKeys.get(* getValue("Time-Course").pKEY));

  if (!mpSteadyState && !mpTrajectory) return false;

  if (mpSteadyState)
    {
      mpSteadyState->initialize();
      ContainerList.push_back(mpSteadyState);
    }
  if (mpTrajectory)
    {
      mpTrajectory->initialize();
      ContainerList.push_back(mpTrajectory);
    }

  buildOptItemListFromParameterGroup();

  unsigned C_INT32 i;
  unsigned C_INT32 Size = mOptItemList.size();

  mUpdateMethods.resize(Size);
  mSolutionVariables.resize(Size);
  mOriginalVariables.resize(Size);

  std::vector< COptItem * >::iterator it = mOptItemList.begin();
  std::vector< COptItem * >::iterator end = mOptItemList.end();

  for (i = 0; it != end; ++it, i++)
    {
      if (!(*it)->compile(ContainerList)) return false;
      mUpdateMethods[i] = (*it)->getUpdateMethod();
      mOriginalVariables[i] = *(*it)->getObjectValue();
    }

  createObjectiveFunction();
  if (!mpFunction) return false;

  return mpFunction->compile(ContainerList);
}

bool COptProblem::restore()
{
  unsigned C_INT32 i, imax = mOptItemList.size();

  // set the original paramter values
  for (i = 0; i < imax; i++)
    (*mUpdateMethods[i])(mOriginalVariables[i]);

  return true;
}

#ifdef WIN32
# pragma warning (default: 4056 4756)
#endif

bool COptProblem::checkParametricConstraints()
{
  std::vector< COptItem * >::const_iterator it = mOptItemList.begin();
  std::vector< COptItem * >::const_iterator end = mOptItemList.end();

  for (; it != end; ++it)
    if ((*it)->checkConstraint()) return false;

  return true;
}

bool COptProblem::checkFunctionalConstraints()
{
  return true; // :TODO:
}

/**
 * calculate() decides whether the problem is a steady state problem or a
 * trajectory problem based on whether the pointer to that type of problem
 * is null or not.  It then calls the process() method for that type of
 * problem.  Currently process takes ofstream& as a parameter but it will
 * change so that process() takes no parameters.
 */
bool COptProblem::calculate()
{
  mCounter += 1;

  try
    {
      if (mpSteadyState != NULL)
        {
          //((CSteadyStateProblem *) mpSteadyState->getProblem())->
          //setInitialState(mpSteadyState->getProblem()->getModel()->getInitialState());
          mpSteadyState->process();
        }

      if (mpTrajectory != NULL)
        {
          //((CTrajectoryProblem *) mpTrajectory->getProblem())->
          //setInitialState(mpTrajectory->getProblem()->getModel()->getInitialState());
          mpTrajectory->process(CCopasiTask::NO_OUTPUT);
        }

      mCalculateValue = mpFunction->calcValue();
    }

  catch (...)
    {
      mCalculateValue = DBL_MAX;
    }

  if (mpCallBack) return mpCallBack->progress(mhCounter);

  return true;
}

const C_FLOAT64 & COptProblem::getCalculateValue() const
{return mCalculateValue;}

void COptProblem::setSolutionVariables(const CVector< C_FLOAT64 > & variables)
{mSolutionVariables = variables;}

const CVector< C_FLOAT64 > & COptProblem::getSolutionVariables() const
  {return mSolutionVariables;}

bool COptProblem::setSolutionValue(const C_FLOAT64 & value)
{
  mSolutionValue = value;
  if (mpCallBack) return mpCallBack->progress(mhSolutionValue);

  return true;
}

const C_FLOAT64 & COptProblem::getSolutionValue() const
{return mSolutionValue;}

// set the type of problem : Steady State OR Trajectory
void COptProblem::setProblemType(ProblemType type)
{
  // :TODO:
  if (type == SteadyState)
    mpSteadyState = new CSteadyStateTask(/*this*/NULL);
  if (type == Trajectory)
    mpTrajectory = new CTrajectoryTask(/*this*/NULL);
}

COptItem & COptProblem::getOptItem(const unsigned C_INT32 & index)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  assert(index < mOptItemList.size());

  return *mOptItemList[index];
}

const unsigned C_INT32 COptProblem::getOptItemSize() const
{return getValue("OptimizationItemList").pGROUP->size();}

COptItem & COptProblem::addOptItem(const CCopasiObjectName & objectCN)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  unsigned C_INT32 index = getOptItemSize();

  CCopasiParameterGroup * pOptimizationItemList = (CCopasiParameterGroup *) getParameter("OptimizationItemList");

  pOptimizationItemList->addGroup("OptimizationItem");

  CCopasiParameterGroup * pOptItem =
    (CCopasiParameterGroup *) pOptimizationItemList->getParameter(index);

  assert(pOptItem != NULL);

  COptItem * pTmp = new COptItem(*pOptItem);

  //pTmp->setLowerBound(

  if (!pTmp->initialize(objectCN)) fatalError();

  mOptItemList.push_back(pTmp);

  return *pTmp;
}

bool COptProblem::removeOptItem(const unsigned C_INT32 & index)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  if (!(index < mOptItemList.size())) return false;

  pdelete(mOptItemList[index]);
  mOptItemList.erase(mOptItemList.begin() + index);

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->removeParameter(index);
}

bool COptProblem::swapOptItem(const unsigned C_INT32 & iFrom,
                              const unsigned C_INT32 & iTo)
{
  if (mOptItemList.size() != getOptItemSize())
    buildOptItemListFromParameterGroup();

  if (!(iFrom < mOptItemList.size()) ||
      !(iTo < mOptItemList.size()))
    return false;

  COptItem * pTmp = mOptItemList[iFrom];
  mOptItemList[iFrom] = mOptItemList[iTo];
  mOptItemList[iTo] = pTmp;

  return ((CCopasiParameterGroup *) getParameter("OptimizationItemList"))->swap(iFrom, iTo);
}

const std::vector< COptItem * > & COptProblem::getOptItemList() const
  {
    if (mOptItemList.size() != getOptItemSize())
      const_cast<COptProblem *>(this)->buildOptItemListFromParameterGroup();

    return mOptItemList;
  }

const std::vector< UpdateMethod * > & COptProblem::getCalculateVariableUpdateMethods() const
{return mUpdateMethods;}

bool COptProblem::setObjectiveFunction(const std::string & infix)
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->setInfix(infix);
}

const std::string COptProblem::getObjectiveFunction()
{
  if (!mpFunction) createObjectiveFunction();

  return mpFunction->getInfix();
}

bool COptProblem::createObjectiveFunction()
{
  mpFunction =
    dynamic_cast<CExpression *>(GlobalKeys.get(* getValue("ObjectiveFunction").pKEY));

  CCopasiVectorN<CEvaluationTree> & FunctionList =
    CCopasiDataModel::Global->getFunctionList()->loadedFunctions();

  if (!mpFunction)
    {
      std::ostringstream Name;
      Name << "Objective Function";

      int i = 0;

      while (FunctionList.getIndex(Name.str()) != C_INVALID_INDEX)
        {
          i++;
          Name.str("");
          Name << "Objective Function " << i;
        }

      mpFunction = new CExpression(Name.str(), this);
      FunctionList.add(mpFunction, false);

      setValue("ObjectiveFunction", mpFunction->getKey());
    }
  else
    {
      mpFunction->setObjectParent(this);

      if (FunctionList.getIndex(mpFunction->getObjectName()) == C_INVALID_INDEX)
        FunctionList.add(mpFunction, false);
    }

  return true;
}

bool COptProblem::buildOptItemListFromParameterGroup()
{
  bool success = true;

  std::vector< COptItem * >::iterator it = mOptItemList.begin();
  std::vector< COptItem * >::iterator end = mOptItemList.end();

  for (; it != end; ++it)
    pdelete(*it);

  unsigned i, imax = getOptItemSize();
  mOptItemList.resize(imax);

  std::vector<CCopasiParameter *> & List = *getValue("OptimizationItemList").pGROUP;

  for (i = 0; i < imax; i++)
    {
      mOptItemList[i] = new COptItem(* (CCopasiParameterGroup *) List[i]);
      if (!mOptItemList[i]->isValid()) success = false;
    }

  return true;
}
<|endoftext|>


<commit_before>namespace factor
{

extern "C" typedef void (*primitive_type)();
extern const primitive_type primitives[];

#define PRIMITIVE(name) extern "C" void primitive_##name()

}
<commit_msg>added stub PRIMITIVE_GETVM macro<commit_after>namespace factor
{

extern "C" typedef void (*primitive_type)();
extern const primitive_type primitives[];

#define PRIMITIVE(name) extern "C" void primitive_##name()
#define PRIMITIVE_GETVM() vm->
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : D2.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/3/9 17:08:58
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

using shop = tuple<ll, ll>;

ostream &operator<<(ostream &os, shop const &s)
{
  return os << "(" << get<0>(s) << ", " << get<1>(s) << ")";
}

class Solve
{
  static constexpr int C{32};
  int N, M, L;
  ll T;
  vector<shop> V;
  vector<shop> normal, zero;
  vector<ll> sum;
  vector<vector<ll>> dp;

public:
  Solve(int N, ll T, vector<shop> V) : N{N}, T{T}, V(V)
  {
    make_normal_zero();
    execute_dp();
    cout << calc_ans() << endl;
  }

private:
  static bool compare_normal(shop const &left, shop const &right)
  {
    return (get<0>(right) - 1) * get<1>(left) - (get<0>(left) - 1) * get<1>(right) <= 0;
  }

  static bool compare_zero(shop const &left, shop const &right)
  {
    return get<1>(left) <= get<1>(right);
  }

  ll f(int i, ll x)
  {
    return get<0>(normal[i]) * x + get<1>(normal[i]);
  }

  void make_normal_zero()
  {
    for (auto i = 0; i < N; ++i)
    {
      if (get<0>(V[i]) >= 2)
      {
        normal.push_back(V[i]);
      }
      else
      {
        zero.push_back(V[i]);
      }
    }
    exit(0);
    M = normal.size();
    L = zero.size();
    sort(normal.begin(), normal.end(), compare_normal);
    sort(zero.begin(), zero.end(), compare_zero);
    sum = vector<ll>(L + 1, 0);
    for (auto i = 0; i < L; ++i)
    {
      sum[i + 1] = sum[i] + get<1>(zero[i]);
    }
  }

  void execute_dp()
  {
    dp = vector<vector<ll>>(M + 1, vector<ll>(C, infty));
    dp[0][0] = 0;
    for (auto i = 0; i < M; ++i)
    {
      dp[i + 1][0] = dp[i][0];
      for (auto j = 1; j < C; ++j)
      {
        dp[i + 1][j] = min(dp[i][j], f(i, dp[i][j - 1]));
      }
    }
  }

  int calc_ans()
  {
    int ans{0};
    for (auto i = 0; i < C; ++i)
    {
      ll remain{T - dp[M][i]};
      if (remain < 0)
      {
        continue;
      }
      int z{static_cast<int>(upper_bound(sum.begin(), sum.end(), remain) - sum.begin()) - 1};
      ch_max(ans, z + i);
    }
    return ans;
  }
};

int main()
{
  int N;
  ll T;
  cin >> N >> T;
  vector<shop> V(N);
  for (auto i = 0; i < N; ++i)
  {
    ll a, b;
    cin >> a >> b;
    V[i] = shop(a + 1, a + b + 1);
  }
  Solve solve(N, T, V);
}
<commit_msg>submit D2.cpp to 'D - Manga Market' (hitachi2020) [C++14 (GCC 5.4.1)]<commit_after>#define DEBUG 1
/**
 * File    : D2.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/3/9 17:08:58
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

using shop = tuple<ll, ll>;

ostream &operator<<(ostream &os, shop const &s)
{
  return os << "(" << get<0>(s) << ", " << get<1>(s) << ")";
}

class Solve
{
  static constexpr int C{32};
  int N, M, L;
  ll T;
  vector<shop> V;
  vector<shop> normal, zero;
  vector<ll> sum;
  vector<vector<ll>> dp;

public:
  Solve(int N, ll T, vector<shop> V) : N{N}, T{T}, V(V)
  {
    make_normal_zero();
    execute_dp();
    cout << calc_ans() << endl;
  }

private:
  static bool compare_normal(shop const &left, shop const &right)
  {
    return (get<0>(right) - 1) * get<1>(left) - (get<0>(left) - 1) * get<1>(right) <= 0;
  }

  static bool compare_zero(shop const &left, shop const &right)
  {
    return get<1>(left) <= get<1>(right);
  }

  ll f(int i, ll x)
  {
    return get<0>(normal[i]) * x + get<1>(normal[i]);
  }

  void make_normal_zero()
  {
    for (auto i = 0; i < N; ++i)
    {
      if (get<0>(V[i]) >= 2)
      {
        normal.push_back(V[i]);
      }
      else
      {
        zero.push_back(V[i]);
      }
    }
    M = normal.size();
    L = zero.size();
    sort(normal.begin(), normal.end(), compare_normal);
    sort(zero.begin(), zero.end(), compare_zero);
    exit(0);
    sum = vector<ll>(L + 1, 0);
    for (auto i = 0; i < L; ++i)
    {
      sum[i + 1] = sum[i] + get<1>(zero[i]);
    }
  }

  void execute_dp()
  {
    dp = vector<vector<ll>>(M + 1, vector<ll>(C, infty));
    dp[0][0] = 0;
    for (auto i = 0; i < M; ++i)
    {
      dp[i + 1][0] = dp[i][0];
      for (auto j = 1; j < C; ++j)
      {
        dp[i + 1][j] = min(dp[i][j], f(i, dp[i][j - 1]));
      }
    }
  }

  int calc_ans()
  {
    int ans{0};
    for (auto i = 0; i < C; ++i)
    {
      ll remain{T - dp[M][i]};
      if (remain < 0)
      {
        continue;
      }
      int z{static_cast<int>(upper_bound(sum.begin(), sum.end(), remain) - sum.begin()) - 1};
      ch_max(ans, z + i);
    }
    return ans;
  }
};

int main()
{
  int N;
  ll T;
  cin >> N >> T;
  vector<shop> V(N);
  for (auto i = 0; i < N; ++i)
  {
    ll a, b;
    cin >> a >> b;
    V[i] = shop(a + 1, a + b + 1);
  }
  Solve solve(N, T, V);
}
<|endoftext|>


<commit_before>#include <bits/stdc++.h>
#include "max_flow_dinic.h"

using namespace std;

vector<vector<pair<int, int>>> gomory_hu_tree(max_flow_dinic &flow) {
    int n = flow.g.size();
    vector<vector<pair<int, int>>> t(n, vector<pair<int, int>>());
    vector<int> p(n);
    for (int i = 1; i < n; i++) {
        flow.clear_flow();
        int f = flow.max_flow(i, p[i]);
        vector<bool> cut = flow.min_cut();
        for (int j = i + 1; j < n; j++)
            if (cut[j] == cut[i] && p[j] == p[i])
                p[j] = i;
        t[p[i]].emplace_back(i, f);
    }
    return t;
}

// usage example
int main() {
    int capacity[][3] = {{0, 3, 2},
                         {0, 0, 2},
                         {0, 0, 0}};
    int n = 3;
    max_flow_dinic flow(n);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (capacity[i][j] != 0)
                flow.add_bidi_edge(i, j, capacity[i][j]);

    vector<vector<pair<int, int>>> t = gomory_hu_tree(flow);
    for (int u = 0; u < n; ++u)
        for (auto[v, f]:t[u])
            cout << u << " " << v << " " << f << endl;
}
<commit_msg>update<commit_after>#include <bits/stdc++.h>
#include "max_flow_dinic.h"

using namespace std;

vector<vector<pair<int, int>>> gomory_hu_tree(max_flow_dinic &flow) {
    int n = flow.graph.size();
    vector<vector<pair<int, int>>> t(n, vector<pair<int, int>>());
    vector<int> p(n);
    for (int i = 1; i < n; i++) {
        flow.clear_flow();
        int f = flow.max_flow(i, p[i]);
        vector<bool> cut = flow.min_cut();
        for (int j = i + 1; j < n; j++)
            if (cut[j] == cut[i] && p[j] == p[i])
                p[j] = i;
        t[p[i]].emplace_back(i, f);
    }
    return t;
}

// usage example
int main() {
    int capacity[][3] = {{0, 3, 2},
                         {0, 0, 2},
                         {0, 0, 0}};
    int n = 3;
    max_flow_dinic flow(n);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (capacity[i][j] != 0)
                flow.add_bidi_edge(i, j, capacity[i][j]);

    vector<vector<pair<int, int>>> t = gomory_hu_tree(flow);
    for (int u = 0; u < n; ++u)
        for (auto[v, f]:t[u])
            cout << u << " " << v << " " << f << endl;
}
<|endoftext|>


<commit_before>/** \file   ControlNumberGuesser.cc
 *  \brief  Implementation of the ControlNumberGuesser class.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "ControlNumberGuesser.h"
#include <algorithm>
#include <iterator>
#include <vector>
#include "StringUtil.h"
#include "TextUtil.h"
#include "util.h"

static kyotocabinet::HashDB *CreateOrOpenKeyValueDB(const std::string &db_path) {
    auto db(new kyotocabinet::HashDB());
    if (not (db->open(db_path, kyotocabinet::HashDB::OWRITER | kyotocabinet::HashDB::OCREATE)))
        LOG_ERROR("failed to open or create \"" + db_path + "\"!");
    return db;
}

static const std::string MATCH_DB_PREFIX("/usr/local/var/lib/tuelib/normalised_");

ControlNumberGuesser::ControlNumberGuesser(const OpenMode open_mode) {
    const std::string TITLES_DB_PATH(MATCH_DB_PREFIX + "titles.db");
    const std::string AUTHORS_DB_PATH(MATCH_DB_PREFIX + "authors.db");

    if (open_mode == CLEAR_DATABASES) {
        ::unlink(TITLES_DB_PATH.c_str());
        ::unlink(AUTHORS_DB_PATH.c_str());
    }

    titles_db_  = CreateOrOpenKeyValueDB(TITLES_DB_PATH);
    authors_db_ = CreateOrOpenKeyValueDB(AUTHORS_DB_PATH);
}

void ControlNumberGuesser::insertTitle(const std::string &title, const std::string &control_number) {
    const auto normalised_title(NormaliseTitle(title));
    if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
        LOG_DEBUG("in ControlNumberGuesser::insertTitle: normalised_title=\"" + normalised_title + "\".");
    if (unlikely(normalised_title.empty()))
        LOG_WARNING("Empty normalised title in record w/ control number: " + control_number);
    else {
        std::string control_numbers;
        if (titles_db_->get(normalised_title, &control_numbers))
            control_numbers += "\0" + control_number;
        else
            control_numbers = control_number;
        if (unlikely(not titles_db_->set(normalised_title, control_numbers)))
            LOG_ERROR("failed to insert normalised title into the database!");
    }
}

void ControlNumberGuesser::insertAuthors(const std::set<std::string> &authors, const std::string &control_number) {
    for (const auto author : authors) {
        const auto normalised_author_name(TextUtil::UTF8ToLower(NormaliseAuthorName(author)));
        if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
            LOG_DEBUG("in ControlNumberGuesser::insertAuthors: normalised_author_name=\"" + normalised_author_name + "\".");
        std::string control_numbers;
        if (authors_db_->get(normalised_author_name, &control_numbers))
            control_numbers += "\0" + control_number;
        else
            control_numbers = control_number;
        if (unlikely(not authors_db_->set(normalised_author_name, control_numbers)))
            LOG_ERROR("failed to insert normalised author into the database!");
    }
}

std::set<std::string> ControlNumberGuesser::getGuessedControlNumbers(const std::string &title, const std::vector<std::string> &authors) const
{
    const auto normalised_title(TextUtil::UTF8ToLower(NormaliseTitle(title)));
    if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
        LOG_DEBUG("in ControlNumberGuesser::getGuessedControlNumbers: normalised_title=\"" + normalised_title + "\".");
    std::string concatenated_title_control_numbers;
    std::vector<std::string> title_control_numbers;
    if (not titles_db_->get(normalised_title, &concatenated_title_control_numbers)
        or StringUtil::Split(concatenated_title_control_numbers, '\0', &title_control_numbers) == 0)
        return { };

    std::vector<std::string> all_author_control_numbers;
    for (const auto &author : authors) {
        const auto normalised_author(TextUtil::UTF8ToLower(NormaliseTitle(author)));
        if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
            LOG_DEBUG("in ControlNumberGuesser::getGuessedControlNumbers: normalised_author=\"" + normalised_author + "\".");
        std::string concatenated_author_control_numbers;
        std::set<std::string> author_control_numbers;
        if (authors_db_->get(normalised_author, &concatenated_author_control_numbers)) {
            StringUtil::Split(concatenated_author_control_numbers, '\0', &author_control_numbers);
            for (const auto author_control_number : author_control_numbers)
                all_author_control_numbers.emplace_back(author_control_number);
        }
    }
    if (all_author_control_numbers.empty())
        return { };

    std::sort(title_control_numbers.begin(), title_control_numbers.end());
    std::sort(all_author_control_numbers.begin(), all_author_control_numbers.end());
    std::vector<std::string> common_control_numbers;
    std::set_intersection(title_control_numbers.begin(), title_control_numbers.end(),
                          all_author_control_numbers.begin(), all_author_control_numbers.end(),
                          std::back_inserter(common_control_numbers));

    return std::set<std::string>(common_control_numbers.cbegin(), common_control_numbers.cend());
}

std::string ControlNumberGuesser::NormaliseTitle(const std::string &title) {
    std::wstring wtitle;
    if (unlikely(not TextUtil::UTF8ToWCharString(title, &wtitle)))
        LOG_ERROR("failed to convert \"" + title + "\" to a wide character string!");

    std::wstring normalised_title;
    bool space_separator_seen(true);
    for (const auto ch : wtitle) {
        if (TextUtil::IsGeneralPunctuationCharacter(ch) or ch == '-' or TextUtil::IsSpaceSeparatorCharacter(ch)) {
            if (not space_separator_seen)
                normalised_title += ' ';
            space_separator_seen = true;
        } else {
            space_separator_seen = false;
            normalised_title += ch;
        }
    }
    if (not normalised_title.empty() and TextUtil::IsSpaceSeparatorCharacter(normalised_title.back()))
        normalised_title.resize(normalised_title.size() - 1);

    TextUtil::ToLower(&normalised_title);

    std::string utf8_normalised_title;
    if (unlikely(not TextUtil::WCharToUTF8String(normalised_title, &utf8_normalised_title)))
        LOG_ERROR("failed to convert a wstring to an UTF8 string!");

    return utf8_normalised_title;
}

std::string ControlNumberGuesser::NormaliseAuthorName(const std::string &author_name) {
    auto trimmed_author_name = StringUtil::TrimWhite(author_name);
    const auto comma_pos(trimmed_author_name.find(','));
    if (comma_pos != std::string::npos)
        trimmed_author_name = StringUtil::TrimWhite(trimmed_author_name.substr(comma_pos + 1) + " "
                                                    + trimmed_author_name.substr(0, comma_pos));

    std::string normalised_author_name;
    bool space_seen(false);
    for (const char ch : trimmed_author_name) {
        switch (ch) {
        case '.':
            normalised_author_name += ch;
            normalised_author_name += ' ';
            space_seen = true;
            break;
        case ' ':
            if (not space_seen)
                normalised_author_name += ' ';
            space_seen = true;
            break;
        default:
            normalised_author_name += ch;
            space_seen = false;
        }
    }

    return normalised_author_name;
}
<commit_msg>Fixed some obvious bugs.<commit_after>/** \file   ControlNumberGuesser.cc
 *  \brief  Implementation of the ControlNumberGuesser class.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "ControlNumberGuesser.h"
#include <algorithm>
#include <iterator>
#include <vector>
#include "StringUtil.h"
#include "TextUtil.h"
#include "util.h"

static kyotocabinet::HashDB *CreateOrOpenKeyValueDB(const std::string &db_path) {
    auto db(new kyotocabinet::HashDB());
    if (not (db->open(db_path, kyotocabinet::HashDB::OWRITER | kyotocabinet::HashDB::OCREATE)))
        LOG_ERROR("failed to open or create \"" + db_path + "\"!");
    return db;
}

static const std::string MATCH_DB_PREFIX("/usr/local/var/lib/tuelib/normalised_");

ControlNumberGuesser::ControlNumberGuesser(const OpenMode open_mode) {
    const std::string TITLES_DB_PATH(MATCH_DB_PREFIX + "titles.db");
    const std::string AUTHORS_DB_PATH(MATCH_DB_PREFIX + "authors.db");

    if (open_mode == CLEAR_DATABASES) {
        ::unlink(TITLES_DB_PATH.c_str());
        ::unlink(AUTHORS_DB_PATH.c_str());
    }

    titles_db_  = CreateOrOpenKeyValueDB(TITLES_DB_PATH);
    authors_db_ = CreateOrOpenKeyValueDB(AUTHORS_DB_PATH);
}

void ControlNumberGuesser::insertTitle(const std::string &title, const std::string &control_number) {
    const auto normalised_title(NormaliseTitle(title));
    if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
        LOG_DEBUG("in ControlNumberGuesser::insertTitle: normalised_title=\"" + normalised_title + "\".");
    if (unlikely(normalised_title.empty()))
        LOG_WARNING("Empty normalised title in record w/ control number: " + control_number);
    else {
        std::string control_numbers;
        if (titles_db_->get(normalised_title, &control_numbers))
            control_numbers += "\0" + control_number;
        else
            control_numbers = control_number;
        if (unlikely(not titles_db_->set(normalised_title, control_numbers)))
            LOG_ERROR("failed to insert normalised title into the database!");
    }
}

void ControlNumberGuesser::insertAuthors(const std::set<std::string> &authors, const std::string &control_number) {
    for (const auto author : authors) {
        const auto normalised_author_name(TextUtil::UTF8ToLower(NormaliseAuthorName(author)));
        if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
            LOG_DEBUG("in ControlNumberGuesser::insertAuthors: normalised_author_name=\"" + normalised_author_name + "\".");
        std::string control_numbers;
        if (authors_db_->get(normalised_author_name, &control_numbers))
            control_numbers += "\0" + control_number;
        else
            control_numbers = control_number;
        if (unlikely(not authors_db_->set(normalised_author_name, control_numbers)))
            LOG_ERROR("failed to insert normalised author into the database!");
    }
}

std::set<std::string> ControlNumberGuesser::getGuessedControlNumbers(const std::string &title, const std::vector<std::string> &authors) const
{
    const auto normalised_title(NormaliseTitle(title));
    if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
        LOG_DEBUG("in ControlNumberGuesser::getGuessedControlNumbers: normalised_title=\"" + normalised_title + "\".");
    std::string concatenated_title_control_numbers;
    std::vector<std::string> title_control_numbers;
    if (not titles_db_->get(normalised_title, &concatenated_title_control_numbers)
        or StringUtil::Split(concatenated_title_control_numbers, '\0', &title_control_numbers) == 0)
        return { };

    std::vector<std::string> all_author_control_numbers;
    for (const auto &author : authors) {
        const auto normalised_author(NormaliseAuthorName(author));
        if (logger->getMinimumLogLevel() >= Logger::LL_DEBUG)
            LOG_DEBUG("in ControlNumberGuesser::getGuessedControlNumbers: normalised_author=\"" + normalised_author + "\".");
        std::string concatenated_author_control_numbers;
        std::set<std::string> author_control_numbers;
        if (authors_db_->get(normalised_author, &concatenated_author_control_numbers)) {
            StringUtil::Split(concatenated_author_control_numbers, '\0', &author_control_numbers);
            for (const auto author_control_number : author_control_numbers)
                all_author_control_numbers.emplace_back(author_control_number);
        }
    }
    if (all_author_control_numbers.empty())
        return { };

    std::sort(title_control_numbers.begin(), title_control_numbers.end());
    std::sort(all_author_control_numbers.begin(), all_author_control_numbers.end());
    std::vector<std::string> common_control_numbers;
    std::set_intersection(title_control_numbers.begin(), title_control_numbers.end(),
                          all_author_control_numbers.begin(), all_author_control_numbers.end(),
                          std::back_inserter(common_control_numbers));

    return std::set<std::string>(common_control_numbers.cbegin(), common_control_numbers.cend());
}

std::string ControlNumberGuesser::NormaliseTitle(const std::string &title) {
    std::wstring wtitle;
    if (unlikely(not TextUtil::UTF8ToWCharString(title, &wtitle)))
        LOG_ERROR("failed to convert \"" + title + "\" to a wide character string!");

    std::wstring normalised_title;
    bool space_separator_seen(true);
    for (const auto ch : wtitle) {
        if (TextUtil::IsGeneralPunctuationCharacter(ch) or ch == '-' or TextUtil::IsSpaceSeparatorCharacter(ch)) {
            if (not space_separator_seen)
                normalised_title += ' ';
            space_separator_seen = true;
        } else {
            space_separator_seen = false;
            normalised_title += ch;
        }
    }
    if (not normalised_title.empty() and TextUtil::IsSpaceSeparatorCharacter(normalised_title.back()))
        normalised_title.resize(normalised_title.size() - 1);

    TextUtil::ToLower(&normalised_title);

    std::string utf8_normalised_title;
    if (unlikely(not TextUtil::WCharToUTF8String(normalised_title, &utf8_normalised_title)))
        LOG_ERROR("failed to convert a wstring to an UTF8 string!");

    return utf8_normalised_title;
}

std::string ControlNumberGuesser::NormaliseAuthorName(const std::string &author_name) {
    auto trimmed_author_name = StringUtil::TrimWhite(author_name);
    const auto comma_pos(trimmed_author_name.find(','));
    if (comma_pos != std::string::npos)
        trimmed_author_name = StringUtil::TrimWhite(trimmed_author_name.substr(comma_pos + 1) + " "
                                                    + trimmed_author_name.substr(0, comma_pos));

    std::string normalised_author_name;
    bool space_seen(false);
    for (const char ch : trimmed_author_name) {
        switch (ch) {
        case '.':
            normalised_author_name += ch;
            normalised_author_name += ' ';
            space_seen = true;
            break;
        case ' ':
            if (not space_seen)
                normalised_author_name += ' ';
            space_seen = true;
            break;
        default:
            normalised_author_name += ch;
            space_seen = false;
        }
    }

    return TextUtil::UTF8ToLower(normalised_author_name);
}
<|endoftext|>


<commit_before><commit_msg>Made small adjustment to JEWEL_DEBUG_LOG_VALUE macro.<commit_after><|endoftext|>


<commit_before>
#include "itkMacro.h"

#include <iostream>
#include <cstdlib>
#include "svm.h"

namespace otb
{

class LinearKernelFunctor : public GenericKernelFunctorBase
{
public:
  typedef LinearKernelFunctor                 Self;
  typedef GenericKernelFunctorBase            Superclass;

  LinearKernelFunctor() : GenericKernelFunctorBase() {}
  virtual ~LinearKernelFunctor() {}

  // Deep copy operator
  virtual GenericKernelFunctorBase* Clone() const
  {
    return new Self(*this);
  }

  virtual double operator ()(const svm_node *x, const svm_node *y, const svm_parameter&) const
  {
    return this->dot(x, y);
  }

protected:
  LinearKernelFunctor(const Self& copy)
  : Superclass(copy)
  {
    *this = copy;
  }

  LinearKernelFunctor& operator=(const Self& copy)
  {
    Superclass::operator =(copy);
    return *this;
  }
};

}

/**
 * In this test, we approximate a 2-D scalar field.
 * The scattered data is derived from a segmented
 * image.  We write the output to an image for
 * comparison.
 */
int svmGenericKernelTest( int itkNotUsed(argc), char *argv[] )
{
  try
    {
        const char * inputFilename  = argv[1];
        const char * outputFilename = argv[2];
        otb::LinearKernelFunctor lFunctor;

        struct svm_model* model;
        model = svm_load_model(inputFilename, &lFunctor);
        if(model == 0)
        {
                itkGenericExceptionMacro( << "Problem while loading SVM model "
			 << std::string(inputFilename) );
        }

        model->param.kernel_generic->print_parameters();

        if(svm_save_model(outputFilename, model)!=0)
        {
                itkGenericExceptionMacro( << "Problem while saving SVM model "
			 << std::string(outputFilename) );
        }
        if(model != NULL)
          {
          delete model;
          }
    }
  catch( itk::ExceptionObject & err )
    {
    std::cout << "Exception itk::ExceptionObject levee !" << std::endl;
    std::cout << err << std::endl;
    return EXIT_FAILURE;
    }
  catch (...)
    {
    std::cerr << "svmTest exception thrown" << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
};
<commit_msg>COV: Fixing coverity issue 1266747 (Ressource leak)<commit_after>
#include "itkMacro.h"

#include <iostream>
#include <cstdlib>
#include "svm.h"

namespace otb
{

class LinearKernelFunctor : public GenericKernelFunctorBase
{
public:
  typedef LinearKernelFunctor                 Self;
  typedef GenericKernelFunctorBase            Superclass;

  LinearKernelFunctor() : GenericKernelFunctorBase() {}
  virtual ~LinearKernelFunctor() {}

  // Deep copy operator
  virtual GenericKernelFunctorBase* Clone() const
  {
    return new Self(*this);
  }

  virtual double operator ()(const svm_node *x, const svm_node *y, const svm_parameter&) const
  {
    return this->dot(x, y);
  }

protected:
  LinearKernelFunctor(const Self& copy)
    : Superclass(copy)
  {
    *this = copy;
  }

  LinearKernelFunctor& operator=(const Self& copy)
  {
    Superclass::operator =(copy);
    return *this;
  }
};

}

/**
 * In this test, we approximate a 2-D scalar field.
 * The scattered data is derived from a segmented
 * image.  We write the output to an image for
 * comparison.
 */
int svmGenericKernelTest( int itkNotUsed(argc), char *argv[] )
{
  try
    {
    const char * inputFilename  = argv[1];
    const char * outputFilename = argv[2];
    otb::LinearKernelFunctor lFunctor;

    struct svm_model* model;
    model = svm_load_model(inputFilename, &lFunctor);
    if(model == 0)
      {
      itkGenericExceptionMacro( << "Problem while loading SVM model "
                                << std::string(inputFilename) );
      }

    model->param.kernel_generic->print_parameters();

    if(svm_save_model(outputFilename, model)!=0)
      {
      if(model != NULL)
        {
        delete model;
        }
      itkGenericExceptionMacro( << "Problem while saving SVM model "
                                << std::string(outputFilename) );
      }
    if(model != NULL)
      {
      delete model;
      }
    }
  catch( itk::ExceptionObject & err )
    {
    std::cout << "Exception itk::ExceptionObject levee !" << std::endl;
    std::cout << err << std::endl;
    return EXIT_FAILURE;
    }
  catch (...)
    {
    std::cerr << "svmTest exception thrown" << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-2017 Los Alamos National Security, LLC
 *                         All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * LA-CC 10-123
 */

//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

/*!
 @file GenerateProblem.hpp

 HPCG routine
 */

#pragma once

#include "hpcg.hpp"

#include "LegionStuff.hpp"
#include "LegionItems.hpp"
#include "LegionArrays.hpp"
#include "LegionMatrices.hpp"
#include "ReduceSum.hpp"

#include <map>
#include <sstream>
#include <cassert>

inline void
PopulateGlobalToLocalMap(
    SparseMatrix &A,
    LegionRuntime::HighLevel::Context ctx,
    LegionRuntime::HighLevel::Runtime *runtime
) {
    const Geometry *const Ageom = A.geom->data();
    // Make local copies of geometry information.  Use global_int_t since the
    // RHS products in the calculations below may result in global range values.
    const global_int_t nx  = Ageom->nx;
    const global_int_t ny  = Ageom->ny;
    const global_int_t nz  = Ageom->nz;
    const global_int_t npx = Ageom->npx;
    const global_int_t npy = Ageom->npy;
    const global_int_t ipx = Ageom->ipx;
    const global_int_t ipy = Ageom->ipy;
    const global_int_t ipz = Ageom->ipz;
    const global_int_t gnx = nx * npx;
    const global_int_t gny = ny * npy;
    //!< global-to-local mapping
    auto &globalToLocalMap = A.globalToLocalMap;
    //
    for (local_int_t iz = 0; iz < nz; iz++) {
        global_int_t giz = ipz*nz+iz;
        for (local_int_t iy = 0; iy < ny; iy++) {
            global_int_t giy = ipy*ny+iy;
            for (local_int_t ix = 0; ix < nx; ix++) {
                global_int_t gix = ipx*nx+ix;
                local_int_t currentLocalRow = iz*nx*ny+iy*nx+ix;
                global_int_t currentGlobalRow = giz*gnx*gny+giy*gnx+gix;
                globalToLocalMap[currentGlobalRow] = currentLocalRow;
            }
        }
    }
}

/**
 * Tally total number of non-zeros in simulation.
 */
static inline global_int_t
getTotalNumberOfNonZeros(
    SparseMatrix &A,
    LegionRuntime::HighLevel::Context ctx,
    LegionRuntime::HighLevel::Runtime *runtime
) {
    DynamicCollective dcAllreduceSum = *A.dcAllreduceSum->data();
    //
    TaskLauncher tlLocalNZ(LOCAL_NONZEROS_TID, TaskArgument(NULL, 0));
    tlLocalNZ.add_region_requirement(
        RegionRequirement(A.sclrs->logicalRegion, RO_E, A.sclrs->logicalRegion)
    ).add_field(A.sclrs->getFieldID());
    //
    Future future = runtime->execute_task(ctx, tlLocalNZ);
    //
    runtime->defer_dynamic_collective_arrival(ctx, dcAllreduceSum, future);
    dcAllreduceSum = runtime->advance_dynamic_collective(ctx, dcAllreduceSum);
    //
    Future fSum = runtime->get_dynamic_collective_result(ctx, dcAllreduceSum);

    return fSum.get<global_int_t>();
}

/*!
    Reference version of GenerateProblem to generate the sparse matrix, right
    hand side, initial guess, and exact solution.

    @param[in]  A        The known system matrix
    @param[inout] b      The newly allocated and generated right hand side
    vector (if b!=0 on entry)
    @param[inout] x      The newly allocated solution vector with entries set to
    0.0 (if x!=0 on entry)
    @param[inout] xexact The newly allocated solution vector with entries set to
    the exact solution (if the xexact!=0 non-zero on entry)

    @see GenerateGeometry
*/
inline void
GenerateProblem(
    SparseMatrix &A,
    Array<floatType> *b,
    Array<floatType> *x,
    Array<floatType> *xexact,
    LegionRuntime::HighLevel::Context ctx,
    LegionRuntime::HighLevel::Runtime *runtime
) {
    using namespace std;
    const Geometry *const Ageom = A.geom->data();
    // Make local copies of geometry information.  Use global_int_t since the
    // RHS products in the calculations below may result in global range values.
    const global_int_t nx  = Ageom->nx;
    const global_int_t ny  = Ageom->ny;
    const global_int_t nz  = Ageom->nz;
    const global_int_t npx = Ageom->npx;
    const global_int_t npy = Ageom->npy;
    const global_int_t npz = Ageom->npz;
    const global_int_t ipx = Ageom->ipx;
    const global_int_t ipy = Ageom->ipy;
    const global_int_t ipz = Ageom->ipz;
    const global_int_t gnx = nx * npx;
    const global_int_t gny = ny * npy;
    const global_int_t gnz = nz * npz;
    // This is the size of our subblock.
    const local_int_t localNumberOfRows = nx * ny * nz;
    // If this assert fails, it most likely means that the local_int_t is set to
    // int and should be set to.  Throw an exception of the number of rows is
    // less than zero (can happen if int overflow)long long
    assert(localNumberOfRows > 0);
    // We are approximating a 27-point finite element/volume/difference 3D
    // stencil
    const local_int_t numberOfNonzerosPerRow = Ageom->stencilSize;

    // Total number of grid points in mesh
    const global_int_t totalNumberOfRows = ((global_int_t)localNumberOfRows)
                                         * ((global_int_t)Ageom->size);
    // If this assert fails, it most likely means that the global_int_t is set
    // to int and should be set to long long
    assert(totalNumberOfRows > 0);
    ////////////////////////////////////////////////////////////////////////////
    // Allocate arrays
    ////////////////////////////////////////////////////////////////////////////
    if (Ageom->rank == 0) {
        const size_t mn = localNumberOfRows * numberOfNonzerosPerRow;
        const size_t sparseMatMemInB = (
            sizeof(char)         * localNumberOfRows //nonzerosInRow
          + sizeof(global_int_t) * mn                //mtxIndG
          + sizeof(local_int_t)  * mn                //mtxIndL
          + sizeof(floatType)    * mn                //matrixValues
          + sizeof(floatType)    * localNumberOfRows //matrixDiagonal
          + sizeof(global_int_t) * localNumberOfRows //localToGlobalMap
        ) * Ageom->size;
        //
        const size_t vectorsMemInB = (
            (b      ? sizeof(floatType) * localNumberOfRows : 0)
          + (x      ? sizeof(floatType) * localNumberOfRows : 0)
          + (xexact ? sizeof(floatType) * localNumberOfRows : 0)
        ) * Ageom->size;
        //
        const size_t pMemInB = sparseMatMemInB + vectorsMemInB;
        const double pMemInMB = pMemInB/1024.0/1024.0;
        cout << "--> Approximate Generate Problem Memory Footprint="
             << pMemInMB << " MB" << endl;
    }
    char *nonzerosInRow = A.nonzerosInRow->data();
    assert(nonzerosInRow);
    // Interpreted as 2D array
    Array2D<global_int_t> mtxIndG(
        localNumberOfRows, numberOfNonzerosPerRow, A.mtxIndG->data()
    );
    // Interpreted as 2D array
    Array2D<local_int_t> mtxIndL(
        localNumberOfRows, numberOfNonzerosPerRow, A.mtxIndL->data()
    );
    // Interpreted as 2D array
    Array2D<floatType> matrixValues(
        localNumberOfRows, numberOfNonzerosPerRow, A.matrixValues->data()
    );
    //
    floatType *matrixDiagonal = A.matrixDiagonal->data();
    //
    global_int_t *localToGlobalMap = A.localToGlobalMap->data();
    //
    floatType *bv      = nullptr;
    floatType *xv      = nullptr;
    floatType *xexactv = nullptr;
    if (b != 0) {
        bv = b->data(); // Only compute exact solution if requested
        assert(bv);
    }
    if (x != 0) {
        xv = x->data(); // Only compute exact solution if requested
        assert(xv);
    }
    if (xexact != 0) {
        xexactv = xexact->data(); // Only compute exact solution if requested
        assert(xexactv);
    }
#if 0 // TODO
    //!< global-to-local mapping
    auto &globalToLocalMap = A.globalToLocalMap;
#endif
    //
    global_int_t localNumberOfNonzeros = 0;
    //
    for (local_int_t iz=0; iz<nz; iz++) {
        global_int_t giz = ipz*nz+iz;
        for (local_int_t iy=0; iy<ny; iy++) {
            global_int_t giy = ipy*ny+iy;
            for (local_int_t ix=0; ix<nx; ix++) {
                global_int_t gix = ipx*nx+ix;
                local_int_t currentLocalRow = iz*nx*ny+iy*nx+ix;
                global_int_t currentGlobalRow = giz*gnx*gny+giy*gnx+gix;
#if 0 // TODO
                globalToLocalMap[currentGlobalRow] = currentLocalRow;
#endif
                localToGlobalMap[currentLocalRow] = currentGlobalRow;
                char numberOfNonzerosInRow = 0;
                // Current index in current row
                global_int_t currentIndexG = 0;
                local_int_t currentNonZeroElemIndex = 0;
                for (int sz=-1; sz<=1; sz++) {
                    if (giz+sz>-1 && giz+sz<gnz) {
                        for (int sy=-1; sy<=1; sy++) {
                            if (giy+sy>-1 && giy+sy<gny) {
                                for (int sx=-1; sx<=1; sx++) {
                                    if (gix+sx>-1 && gix+sx<gnx) {
                                        global_int_t curcol = currentGlobalRow
                                                            + sz*gnx*gny
                                                            + sy*gnx+sx;
                                        if (curcol==currentGlobalRow) {
                                            matrixDiagonal[currentLocalRow] = 26.0;
                                            matrixValues(currentLocalRow, currentNonZeroElemIndex) = 26.0;
                                        } else {
                                            matrixValues(currentLocalRow, currentNonZeroElemIndex) = -1.0;
                                        }
                                        currentNonZeroElemIndex++;
                                        mtxIndG(currentLocalRow, currentIndexG++) = curcol;
                                        numberOfNonzerosInRow++;
                                    } // end x bounds test
                                } // end sx loop
                            } // end y bounds test
                        } // end sy loop
                    } // end z bounds test
                } // end sz loop
                nonzerosInRow[currentLocalRow] = numberOfNonzerosInRow;
                localNumberOfNonzeros += numberOfNonzerosInRow;
                if (b!=0) {
                    bv[currentLocalRow] = 26.0
                                        - ((double)(numberOfNonzerosInRow-1));
                }
                if (x!=0) {
                    xv[currentLocalRow] = 0.0;
                }
                if (xexact!=0) {
                    xexactv[currentLocalRow] = 1.0;
                }
            } // end ix loop
        } // end iy loop
    } // end iz loop

    SparseMatrixScalars *Asclrs   = A.sclrs->data();
    Asclrs->totalNumberOfRows     = totalNumberOfRows;
    Asclrs->localNumberOfRows     = localNumberOfRows;
    Asclrs->localNumberOfColumns  = localNumberOfRows;
    Asclrs->localNumberOfNonzeros = localNumberOfNonzeros;
    Asclrs->totalNumberOfNonzeros = getTotalNumberOfNonZeros(A, ctx, runtime);
    // If this assert fails, it most likely means that the global_int_t is
    // set to int and should be set to long long This assert is usually the
    // first to fail as problem size increases beyond the 32-bit integer
    // range.  Throw an exception of the number of nonzeros is less than
    // zero (can happen if int overflow)
    assert(Asclrs->totalNumberOfNonzeros > 0);
}
<commit_msg>Minor cleanup.<commit_after>/**
 * Copyright (c) 2016-2017 Los Alamos National Security, LLC
 *                         All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * LA-CC 10-123
 */

//@HEADER
// ***************************************************
//
// HPCG: High Performance Conjugate Gradient Benchmark
//
// Contact:
// Michael A. Heroux ( maherou@sandia.gov)
// Jack Dongarra     (dongarra@eecs.utk.edu)
// Piotr Luszczek    (luszczek@eecs.utk.edu)
//
// ***************************************************
//@HEADER

/*!
 @file GenerateProblem.hpp

 HPCG routine
 */

#pragma once

#include "hpcg.hpp"

#include "LegionStuff.hpp"
#include "LegionItems.hpp"
#include "LegionArrays.hpp"
#include "LegionMatrices.hpp"
#include "ReduceSum.hpp"

#include <map>
#include <sstream>
#include <cassert>

inline void
PopulateGlobalToLocalMap(
    SparseMatrix &A,
    LegionRuntime::HighLevel::Context ctx,
    LegionRuntime::HighLevel::Runtime *runtime
) {
    const Geometry *const Ageom = A.geom->data();
    // Make local copies of geometry information.  Use global_int_t since the
    // RHS products in the calculations below may result in global range values.
    const global_int_t nx  = Ageom->nx;
    const global_int_t ny  = Ageom->ny;
    const global_int_t nz  = Ageom->nz;
    const global_int_t npx = Ageom->npx;
    const global_int_t npy = Ageom->npy;
    const global_int_t ipx = Ageom->ipx;
    const global_int_t ipy = Ageom->ipy;
    const global_int_t ipz = Ageom->ipz;
    const global_int_t gnx = nx * npx;
    const global_int_t gny = ny * npy;
    //!< global-to-local mapping
    auto &globalToLocalMap = A.globalToLocalMap;
    //
    for (local_int_t iz = 0; iz < nz; iz++) {
        global_int_t giz = ipz*nz+iz;
        for (local_int_t iy = 0; iy < ny; iy++) {
            global_int_t giy = ipy*ny+iy;
            for (local_int_t ix = 0; ix < nx; ix++) {
                global_int_t gix = ipx*nx+ix;
                local_int_t currentLocalRow = iz*nx*ny+iy*nx+ix;
                global_int_t currentGlobalRow = giz*gnx*gny+giy*gnx+gix;
                globalToLocalMap[currentGlobalRow] = currentLocalRow;
            }
        }
    }
}

/**
 * Tally total number of non-zeros in simulation.
 */
static inline global_int_t
getTotalNumberOfNonZeros(
    SparseMatrix &A,
    LegionRuntime::HighLevel::Context ctx,
    LegionRuntime::HighLevel::Runtime *runtime
) {
    DynamicCollective dcAllreduceSum = *A.dcAllreduceSum->data();
    //
    TaskLauncher tlLocalNZ(LOCAL_NONZEROS_TID, TaskArgument(NULL, 0));
    tlLocalNZ.add_region_requirement(
        RegionRequirement(A.sclrs->logicalRegion, RO_E, A.sclrs->logicalRegion)
    ).add_field(A.sclrs->getFieldID());
    //
    Future future = runtime->execute_task(ctx, tlLocalNZ);
    //
    runtime->defer_dynamic_collective_arrival(ctx, dcAllreduceSum, future);
    dcAllreduceSum = runtime->advance_dynamic_collective(ctx, dcAllreduceSum);
    //
    Future fSum = runtime->get_dynamic_collective_result(ctx, dcAllreduceSum);

    return fSum.get<global_int_t>();
}

/*!
    Reference version of GenerateProblem to generate the sparse matrix, right
    hand side, initial guess, and exact solution.

    @param[in]  A        The known system matrix
    @param[inout] b      The newly allocated and generated right hand side
    vector (if b!=0 on entry)
    @param[inout] x      The newly allocated solution vector with entries set to
    0.0 (if x!=0 on entry)
    @param[inout] xexact The newly allocated solution vector with entries set to
    the exact solution (if the xexact!=0 non-zero on entry)

    @see GenerateGeometry
*/
inline void
GenerateProblem(
    SparseMatrix &A,
    Array<floatType> *b,
    Array<floatType> *x,
    Array<floatType> *xexact,
    LegionRuntime::HighLevel::Context ctx,
    LegionRuntime::HighLevel::Runtime *runtime
) {
    using namespace std;
    const Geometry *const Ageom = A.geom->data();
    // Make local copies of geometry information.  Use global_int_t since the
    // RHS products in the calculations below may result in global range values.
    const global_int_t nx  = Ageom->nx;
    const global_int_t ny  = Ageom->ny;
    const global_int_t nz  = Ageom->nz;
    const global_int_t npx = Ageom->npx;
    const global_int_t npy = Ageom->npy;
    const global_int_t npz = Ageom->npz;
    const global_int_t ipx = Ageom->ipx;
    const global_int_t ipy = Ageom->ipy;
    const global_int_t ipz = Ageom->ipz;
    const global_int_t gnx = nx * npx;
    const global_int_t gny = ny * npy;
    const global_int_t gnz = nz * npz;
    // This is the size of our subblock.
    const local_int_t localNumberOfRows = nx * ny * nz;
    // If this assert fails, it most likely means that the local_int_t is set to
    // int and should be set to.  Throw an exception of the number of rows is
    // less than zero (can happen if int overflow)long long
    assert(localNumberOfRows > 0);
    // We are approximating a 27-point finite element/volume/difference 3D
    // stencil
    const local_int_t numberOfNonzerosPerRow = Ageom->stencilSize;

    // Total number of grid points in mesh
    const global_int_t totalNumberOfRows = ((global_int_t)localNumberOfRows)
                                         * ((global_int_t)Ageom->size);
    // If this assert fails, it most likely means that the global_int_t is set
    // to int and should be set to long long
    assert(totalNumberOfRows > 0);
    ////////////////////////////////////////////////////////////////////////////
    // Allocate arrays
    ////////////////////////////////////////////////////////////////////////////
    if (Ageom->rank == 0) {
        const size_t mn = localNumberOfRows * numberOfNonzerosPerRow;
        const size_t sparseMatMemInB = (
            sizeof(char)         * localNumberOfRows //nonzerosInRow
          + sizeof(global_int_t) * mn                //mtxIndG
          + sizeof(local_int_t)  * mn                //mtxIndL
          + sizeof(floatType)    * mn                //matrixValues
          + sizeof(floatType)    * localNumberOfRows //matrixDiagonal
          + sizeof(global_int_t) * localNumberOfRows //localToGlobalMap
        ) * Ageom->size;
        //
        const size_t vectorsMemInB = (
            (b      ? sizeof(floatType) * localNumberOfRows : 0)
          + (x      ? sizeof(floatType) * localNumberOfRows : 0)
          + (xexact ? sizeof(floatType) * localNumberOfRows : 0)
        ) * Ageom->size;
        //
        const size_t pMemInB = sparseMatMemInB + vectorsMemInB;
        const double pMemInMB = pMemInB/1024.0/1024.0;
        cout << "--> Approximate Generate Problem Memory Footprint="
             << pMemInMB << " MB" << endl;
    }
    char *nonzerosInRow = A.nonzerosInRow->data();
    assert(nonzerosInRow);
    // Interpreted as 2D array
    Array2D<global_int_t> mtxIndG(
        localNumberOfRows, numberOfNonzerosPerRow, A.mtxIndG->data()
    );
    // Interpreted as 2D array
    Array2D<local_int_t> mtxIndL(
        localNumberOfRows, numberOfNonzerosPerRow, A.mtxIndL->data()
    );
    // Interpreted as 2D array
    Array2D<floatType> matrixValues(
        localNumberOfRows, numberOfNonzerosPerRow, A.matrixValues->data()
    );
    //
    floatType *matrixDiagonal = A.matrixDiagonal->data();
    //
    global_int_t *localToGlobalMap = A.localToGlobalMap->data();
    //
    floatType *bv      = nullptr;
    floatType *xv      = nullptr;
    floatType *xexactv = nullptr;
    if (b != 0) {
        bv = b->data(); // Only compute exact solution if requested
        assert(bv);
    }
    if (x != 0) {
        xv = x->data(); // Only compute exact solution if requested
        assert(xv);
    }
    if (xexact != 0) {
        xexactv = xexact->data(); // Only compute exact solution if requested
        assert(xexactv);
    }
    //
    global_int_t localNumberOfNonzeros = 0;
    //
    for (local_int_t iz=0; iz<nz; iz++) {
        global_int_t giz = ipz*nz+iz;
        for (local_int_t iy=0; iy<ny; iy++) {
            global_int_t giy = ipy*ny+iy;
            for (local_int_t ix=0; ix<nx; ix++) {
                global_int_t gix = ipx*nx+ix;
                local_int_t currentLocalRow = iz*nx*ny+iy*nx+ix;
                global_int_t currentGlobalRow = giz*gnx*gny+giy*gnx+gix;
                localToGlobalMap[currentLocalRow] = currentGlobalRow;
                char numberOfNonzerosInRow = 0;
                // Current index in current row
                global_int_t currentIndexG = 0;
                local_int_t currentNonZeroElemIndex = 0;
                for (int sz=-1; sz<=1; sz++) {
                    if (giz+sz>-1 && giz+sz<gnz) {
                        for (int sy=-1; sy<=1; sy++) {
                            if (giy+sy>-1 && giy+sy<gny) {
                                for (int sx=-1; sx<=1; sx++) {
                                    if (gix+sx>-1 && gix+sx<gnx) {
                                        global_int_t curcol = currentGlobalRow
                                                            + sz*gnx*gny
                                                            + sy*gnx+sx;
                                        if (curcol==currentGlobalRow) {
                                            matrixDiagonal[currentLocalRow] = 26.0;
                                            matrixValues(currentLocalRow, currentNonZeroElemIndex) = 26.0;
                                        } else {
                                            matrixValues(currentLocalRow, currentNonZeroElemIndex) = -1.0;
                                        }
                                        currentNonZeroElemIndex++;
                                        mtxIndG(currentLocalRow, currentIndexG++) = curcol;
                                        numberOfNonzerosInRow++;
                                    } // end x bounds test
                                } // end sx loop
                            } // end y bounds test
                        } // end sy loop
                    } // end z bounds test
                } // end sz loop
                nonzerosInRow[currentLocalRow] = numberOfNonzerosInRow;
                localNumberOfNonzeros += numberOfNonzerosInRow;
                if (b!=0) {
                    bv[currentLocalRow] = 26.0
                                        - ((double)(numberOfNonzerosInRow-1));
                }
                if (x!=0) {
                    xv[currentLocalRow] = 0.0;
                }
                if (xexact!=0) {
                    xexactv[currentLocalRow] = 1.0;
                }
            } // end ix loop
        } // end iy loop
    } // end iz loop

    SparseMatrixScalars *Asclrs   = A.sclrs->data();
    Asclrs->totalNumberOfRows     = totalNumberOfRows;
    Asclrs->localNumberOfRows     = localNumberOfRows;
    Asclrs->localNumberOfColumns  = localNumberOfRows;
    Asclrs->localNumberOfNonzeros = localNumberOfNonzeros;
    Asclrs->totalNumberOfNonzeros = getTotalNumberOfNonZeros(A, ctx, runtime);
    // If this assert fails, it most likely means that the global_int_t is
    // set to int and should be set to long long This assert is usually the
    // first to fail as problem size increases beyond the 32-bit integer
    // range.  Throw an exception of the number of nonzeros is less than
    // zero (can happen if int overflow)
    assert(Asclrs->totalNumberOfNonzeros > 0);
}
<|endoftext|>


<commit_before>/****************************************************************
 * Servo                                                        *
 * read joystick data, normalize, write to servo                *
 *                                                              *
 * known issues: if it won't work, open serial monitor then try *
 *                                                              *
 * @author: Navid Kalaei <navidkalaie@gmail.com>                *
 * @github: @navid-kalaei                                       *
 * @license: MIT                                                *
 ****************************************************************/

#include "Arduino.h"
#include "Servo.h"

// time to wait in millis
#define DELAY_TIME 200

#define SERIAL_RATE 9600
#define JOY_PIN_X 0
#define JOY_PIN_Y 1

#define SERVO_PIN 9

// boundries of analogRead()
#define ANALOG_READ_LOW 0
#define ANALOG_READ_HIGH 1023

// boundries for normalizing analogRead() from -90 to +90
#define NORMALIZE_BOUND_LOW -90
#define NORMALIZE_BOUND_HIGH 90
// use this number to shift normalize value be between 0 to 180
#define NORMALIZE_ORIGIN 90

// the value that joystick has at first
// they're usefull in normalizing
short int joyXOrigin = 0;

short int joyXOriginNormalized = 0;

short int joyValueX = 0;

short int joyValueXNormalized = 0;

Servo myServo;

int myServoPos = 0;

short int normalize(short int value){
  /*
   * a wrapper for map built-in function
   *
   * @param value: is within analogRead boundries
   * @return: normalize value within normalize boundries
   */

   // https://www.arduino.cc/en/Reference/Map
   // map(value, fromLow, fromHigh, toLow, toHigh)
   return map(value,
    ANALOG_READ_LOW, ANALOG_READ_HIGH,
    NORMALIZE_BOUND_LOW, NORMALIZE_BOUND_HIGH);
}

void checkBoundries(short int &value){
  /*
   * check if value is between normalized boudries or reset it to a boundry
   *
   * @param value: to check
   * @return: void
   */

   if(value > NORMALIZE_BOUND_HIGH){
     value = NORMALIZE_BOUND_HIGH;
   }
   else if(value < NORMALIZE_BOUND_LOW){
     value = NORMALIZE_BOUND_LOW;
   }
}

void setup(){
  myServo.attach(SERVO_PIN);

  // initialize joystick pins
  pinMode(JOY_PIN_X, INPUT);

  joyXOrigin = analogRead(JOY_PIN_X);

  joyXOriginNormalized = normalize(joyXOrigin);

  // wait until Serail is not available
  while(!Serial);
  Serial.begin(SERIAL_RATE);
}

void loop(){
  joyValueX = analogRead(JOY_PIN_X);
  joyValueXNormalized = normalize(joyValueX) - joyXOriginNormalized;
  checkBoundries(joyValueXNormalized);

  myServoPos = joyValueXNormalized + NORMALIZE_ORIGIN;
  myServo.write(myServoPos);
  //Serial.println(myServoPos);

  // delay(DELAY_TIME);
}
<commit_msg>port servo to user custom_joystick<commit_after>/****************************************************************
 * Servo                                                        *
 * read joystick data, normalize, write to servo                *
 *                                                              *
 * known issues: if it won't work, open serial monitor then try *
 *                                                              *
 * @author: Navid Kalaei <navidkalaie@gmail.com>                *
 * @github: @navid-kalaei                                       *
 * @license: MIT                                                *
 ****************************************************************/

#include "Arduino.h"
#include "Servo.h"
#include "custom_joystick.h"

// time to wait in millis
#define DELAY_TIME 200

#define SERIAL_RATE 9600
#define JOY_PIN_X 0
#define JOY_PIN_Y 1

#define SERVO_PIN 9

// servo can turn from 0 to 180 so it's origin is 90
#define SERVO_ORIGIN 90

custom_joystick joy;

Servo myServo;

int myServoPos = 0;

void setup(){
  joy.attach_pin_x(JOY_PIN_X);
  joy.attach_pin_y(JOY_PIN_Y);
  joy.calibrate();

  myServo.attach(SERVO_PIN);

  // wait until Serail is not available
  // while(!Serial);
  // Serial.begin(SERIAL_RATE);
}

void loop(){
  myServoPos = joy.get_calibrated_x() + SERVO_ORIGIN;
  myServo.write(myServoPos);

  //Serial.println(myServoPos);
  //delay(DELAY_TIME);
}
<|endoftext|>