<commit_before>/**
* @file InertiaSensorFilter.cpp
* Implementation of module InertiaSensorFilter.
* @author Colin Graf (BH-2011)
* @author Heinrich Mellmann (NaoTH-2012)
* adapted from BH-2011
*/

#include "InertiaSensorFilter.h"
#include "Tools/Debug/DebugDrawings.h"
#include "Tools/Debug/DebugModify.h"
#include "Tools/Debug/DebugBufferedOutput.h"
#include "Tools/Math/RotationMatrix.h"
#include "Motion/MorphologyProcessor/ForwardKinematics.h"

//#include "Representations/MotionControl/MotionInfo.h"
//#include "Representations/MotionControl/WalkingEngineOutput.h"

InertiaSensorFilter::InertiaSensorFilter(const MotionBlackBoard& theBlackBoard, InertialModel& theInertialModel)
  :
  theInertialModel(theInertialModel),
  theBlackBoard(theBlackBoard),
  lastTime(0)
{
  p.processNoise = Vector2<double>(0.004f, 0.004f);
  p.accNoise = Vector3<double>(1.0, 1.0, 1.0);
  p.calculatedAccLimit = Vector2<double>(Math::fromDegrees(20.0), Math::fromDegrees(30.0));

  p.calculateConstants();
}

void InertiaSensorFilter::Parameters::calculateConstants()
{
  processCov.c[0].x = Math::sqr(processNoise.x);
  processCov.c[1].y = Math::sqr(processNoise.y);

  sensorCov[0].x = Math::sqr(accNoise.x);
  sensorCov[1].y = Math::sqr(accNoise.y);
  sensorCov[2].z = Math::sqr(accNoise.z);
}

void InertiaSensorFilter::reset()
{
  x = State<>();
  cov = p.processCov;

  lastTime = theBlackBoard.theFrameInfo.getTime() - (unsigned int)(theBlackBoard.theRobotInfo.getBasicTimeStepInSecond());
}

Vector2<double> InertiaSensorFilter::update()
{
  //MODIFY("module:InertiaSensorFilter:parameters", p);

  // check whether the filter shall be reset
  if(lastTime == 0 || theBlackBoard.theFrameInfo.getTime() == lastTime)
  {
    reset();
    return theInertialModel.orientation;
  }

  // update the filter
  if(theBlackBoard.theCalibrationData.calibrated) // use only calibrated data
  {
    double timeScale = theBlackBoard.theFrameInfo.getTimeSince(lastTime) * 0.001;
    predict(RotationMatrix(Vector3<double>(theBlackBoard.theGyrometerData.data.x * timeScale, theBlackBoard.theGyrometerData.data.y * timeScale, 0)));
  }

  // insert calculated rotation
  safeRawAngle = theBlackBoard.theInertialSensorData.data;

  /*
  if((theMotionInfo.motion == MotionRequest::walk || theMotionInfo.motion == MotionRequest::stand ||
      (theMotionInfo.motion == MotionRequest::specialAction && theMotionInfo.specialActionRequest.specialAction == SpecialActionRequest::sitDownKeeper)) &&
     abs(safeRawAngle.x) < p.calculatedAccLimit.x && abs(safeRawAngle.y) < p.calculatedAccLimit.y)
  */
  double mode = 0;
  MODIFY("InertiaSensorFilter:mode",mode);

  if(
    (theBlackBoard.theMotionStatus.currentMotion == motion::stand || theBlackBoard.theMotionStatus.currentMotion == motion::walk)
    //&& ( theBlackBoard.theSupportPolygon.mode & (SupportPolygon::DOUBLE | SupportPolygon::DOUBLE_LEFT | SupportPolygon::DOUBLE_RIGHT) )
    && (theBlackBoard.theGroundContactModel.leftGroundContact || theBlackBoard.theGroundContactModel.rightGroundContact)
    && abs(safeRawAngle.x) < p.calculatedAccLimit.x && abs(safeRawAngle.y) < p.calculatedAccLimit.y
    )
  {
    // use a modeled acceleration, if the feet are on the ground

    RotationMatrix calculatedRotation =
      Kinematics::ForwardKinematics::calcChestFeetRotation(theBlackBoard.theKinematicChain);

    Vector3<double> accGravOnly(calculatedRotation[0].z, calculatedRotation[1].z, calculatedRotation[2].z);
    accGravOnly *= -Math::g;

    PLOT("InertiaSensorFilter:accGravOnly:x", accGravOnly.x);
    PLOT("InertiaSensorFilter:accGravOnly:y", accGravOnly.y);
    PLOT("InertiaSensorFilter:accGravOnly:z", accGravOnly.z);

    PLOT("InertiaSensorFilter:mode", 0);

    readingUpdate(accGravOnly);
  }
  else // insert acceleration sensor values
  {
    PLOT("theCalibrationData.calibrated", theBlackBoard.theCalibrationData.calibrated);

    if(theBlackBoard.theCalibrationData.calibrated) // use only calibrated data
      readingUpdate(theBlackBoard.theAccelerometerData.data);
    else // use the aldebaran sensor as a fallback
      x.rotation = RotationMatrix(Vector3<double>(safeRawAngle.x, safeRawAngle.y, 0.0));

    PLOT("InertiaSensorFilter:mode", 1);
  }

  // fill the representation
  theInertialModel.orientation = Vector2<double>(
                                  atan2(x.rotation[1].z, x.rotation[2].z),
                                  atan2(-x.rotation[0].z, x.rotation[2].z));

  // this removes any kind of z-rotation from internal rotation
  if(theInertialModel.orientation.abs2() < 0.04 * 0.04)
    x.rotation = RotationMatrix(Vector3<double>(theInertialModel.orientation.x, theInertialModel.orientation.y, 0.0));

  // store some data for the next iteration
  lastTime = theBlackBoard.theFrameInfo.getTime();

  // plots
  PLOT("InertiaSensorFilter:orientationX", theInertialModel.orientation.x);
  PLOT("InertiaSensorFilter:orientationY", theInertialModel.orientation.y);

  return theInertialModel.orientation;
}//end update

void InertiaSensorFilter::predict(const RotationMatrix& rotationOffset)
{
  generateSigmaPoints();

  // update sigma points
  for(int i = 0; i < 5; ++i)
    sigmaPoints[i].rotation *= rotationOffset;

  // get new mean and cov
  meanOfSigmaPoints();
  covOfSigmaPoints();

  // add process noise
  cov.c[0].x += p.processCov.c[0].x;
  cov.c[1].y += p.processCov.c[1].y;
}

void InertiaSensorFilter::readingModel(const State<double>& sigmaPoint, Vector3<double>& reading)
{
  reading = Vector3<double>(sigmaPoint.rotation[0].z, sigmaPoint.rotation[1].z, sigmaPoint.rotation[2].z);
  reading *= -Math::g;
}

void InertiaSensorFilter::readingUpdate(const Vector3<double>& reading)
{
  generateSigmaPoints();

  for(int i = 0; i < 5; ++i)
    readingModel(sigmaPoints[i], sigmaReadings[i]);

  meanOfSigmaReadings();

  PLOT("InertiaSensorFilter:expectedAccX", readingMean.x);
  PLOT("InertiaSensorFilter:accX", reading.x);
  PLOT("InertiaSensorFilter:expectedAccY", readingMean.y);
  PLOT("InertiaSensorFilter:accY", reading.y);
  PLOT("InertiaSensorFilter:expectedAccZ", readingMean.z);
  PLOT("InertiaSensorFilter:accZ", reading.z);

  covOfSigmaReadingsAndSigmaPoints();
  covOfSigmaReadings();

  const Matrix2x3<double>& kalmanGain = readingsSigmaPointsCov.transpose() * (readingsCov + p.sensorCov).invert();
  const Vector2<double>& innovation = kalmanGain * (reading - readingMean);
  x += innovation;
  cov -= kalmanGain * readingsSigmaPointsCov;
}

void InertiaSensorFilter::generateSigmaPoints()
{
  cholOfCov();
  sigmaPoints[0] = x;
  sigmaPoints[1] = x + l.c[0];
  sigmaPoints[2] = x + l.c[1];
  sigmaPoints[3] = x + (-l.c[0]);
  sigmaPoints[4] = x + (-l.c[1]);
}

void InertiaSensorFilter::meanOfSigmaPoints()
{
  x = sigmaPoints[0];
  //for(int i = 0; i < 5; ++i) // ~= 0 .. inf
  for(int i = 0; i < 1; ++i)
  {
    Vector2<double> chunk((sigmaPoints[0] - x) +
                    ((sigmaPoints[1] - x) + (sigmaPoints[2] - x)) +
                    ((sigmaPoints[3] - x) + (sigmaPoints[4] - x)));
    chunk /= 5.f;
    x += chunk;
  }
}

void InertiaSensorFilter::covOfSigmaPoints()
{
  cov = tensor(sigmaPoints[0] - x) +
        (tensor(sigmaPoints[1] - x) + tensor(sigmaPoints[2] - x)) +
        (tensor(sigmaPoints[3] - x) + tensor(sigmaPoints[4] - x));
  cov *= 0.5f;
}

template <class V> InertiaSensorFilter::State<V> InertiaSensorFilter::State<V>::operator+(const Vector2<V>& value) const
{
  return State(*this) += value;
}

template <class V> InertiaSensorFilter::State<V>& InertiaSensorFilter::State<V>::operator+=(const Vector2<V>& value)
{
  rotation *= RotationMatrix(rotation.invert() * Vector3<V>(value.x, value.y, V()));
  return *this;
}

template <class V> Vector2<V> InertiaSensorFilter::State<V>::operator-(const State<V>& other) const
{
  const Vector3<V>& rotDiff(other.rotation * ((const RotationMatrix&)(other.rotation.invert() * rotation)).getAngleAxis());
  return Vector2<V>(rotDiff.x, rotDiff.y);
}

void InertiaSensorFilter::cholOfCov()
{
  // improved symmetry
  const double a11 = cov.c[0].x;
  const double a21 = (cov.c[0].y + cov.c[1].x) * 0.5f;

  const double a22 = cov.c[1].y;

  double& l11(l.c[0].x);
  double& l21(l.c[0].y);

  double& l22(l.c[1].y);

  //ASSERT(a11 >= 0.f);
  l11 = sqrt(std::max(a11, 0.0));
  if(l11 == 0.f) l11 = 0.0000000001f;
  l21 = a21 / l11;

  //ASSERT(a22 - l21 * l21 >= 0.f);
  l22 = sqrt(std::max(a22 - l21 * l21, 0.0));
  if(l22 == 0.f) l22 = 0.0000000001f;
}

void InertiaSensorFilter::meanOfSigmaReadings()
{
  readingMean = sigmaReadings[0];
  //for(int i = 0; i < 5; ++i) // ~= 0 .. inf
  for(int i = 0; i < 1; ++i)
  {
    Vector3<double> chunk((sigmaReadings[0] - readingMean) +
                    ((sigmaReadings[1] - readingMean) + (sigmaReadings[2] - readingMean)) +
                    ((sigmaReadings[3] - readingMean) + (sigmaReadings[4] - readingMean)));
    chunk /= 5.f;
    readingMean += chunk;
  }
}

void InertiaSensorFilter::covOfSigmaReadingsAndSigmaPoints()
{
  readingsSigmaPointsCov = (
    (tensor(sigmaReadings[1] - readingMean, l.c[0]) + tensor(sigmaReadings[2] - readingMean, l.c[1])) +
    (tensor(sigmaReadings[3] - readingMean, -l.c[0]) + tensor(sigmaReadings[4] - readingMean, -l.c[1])));
  readingsSigmaPointsCov *= 0.5f;
}

void InertiaSensorFilter::covOfSigmaReadings()
{
  readingsCov = (tensor(sigmaReadings[0] - readingMean) +
                 (tensor(sigmaReadings[1] - readingMean) + tensor(sigmaReadings[2] - readingMean)) +
                 (tensor(sigmaReadings[3] - readingMean) + tensor(sigmaReadings[4] - readingMean)));
  readingsCov *= 0.5f;
}
<commit_msg>fix crash in SimSpark<commit_after>/**
* @file InertiaSensorFilter.cpp
* Implementation of module InertiaSensorFilter.
* @author Colin Graf (BH-2011)
* @author Heinrich Mellmann (NaoTH-2012)
* adapted from BH-2011
*/

#include "InertiaSensorFilter.h"
#include "Tools/Debug/DebugDrawings.h"
#include "Tools/Debug/DebugModify.h"
#include "Tools/Debug/DebugBufferedOutput.h"
#include "Tools/Math/RotationMatrix.h"
#include "Motion/MorphologyProcessor/ForwardKinematics.h"

//#include "Representations/MotionControl/MotionInfo.h"
//#include "Representations/MotionControl/WalkingEngineOutput.h"

InertiaSensorFilter::InertiaSensorFilter(const MotionBlackBoard& theBlackBoard, InertialModel& theInertialModel)
  :
  theInertialModel(theInertialModel),
  theBlackBoard(theBlackBoard),
  lastTime(0)
{
  p.processNoise = Vector2<double>(0.004f, 0.004f);
  p.accNoise = Vector3<double>(1.0, 1.0, 1.0);
  p.calculatedAccLimit = Vector2<double>(Math::fromDegrees(20.0), Math::fromDegrees(30.0));

  p.calculateConstants();
}

void InertiaSensorFilter::Parameters::calculateConstants()
{
  processCov.c[0].x = Math::sqr(processNoise.x);
  processCov.c[1].y = Math::sqr(processNoise.y);

  sensorCov[0].x = Math::sqr(accNoise.x);
  sensorCov[1].y = Math::sqr(accNoise.y);
  sensorCov[2].z = Math::sqr(accNoise.z);
}

void InertiaSensorFilter::reset()
{
  x = State<>();
  cov = p.processCov;

  lastTime = theBlackBoard.theFrameInfo.getTime() - (unsigned int)(theBlackBoard.theRobotInfo.getBasicTimeStepInSecond());
}

Vector2<double> InertiaSensorFilter::update()
{
  //MODIFY("module:InertiaSensorFilter:parameters", p);

  // check whether the filter shall be reset
  if(lastTime == 0 || theBlackBoard.theFrameInfo.getTime() == lastTime)
  {
    reset();
    return theInertialModel.orientation;
  }

  // update the filter
  if(theBlackBoard.theCalibrationData.calibrated) // use only calibrated data
  {
    double timeScale = theBlackBoard.theFrameInfo.getTimeSince(lastTime) * 0.001;
    predict(RotationMatrix(Vector3<double>(theBlackBoard.theGyrometerData.data.x * timeScale, theBlackBoard.theGyrometerData.data.y * timeScale, 0)));
  }

  // insert calculated rotation
  safeRawAngle = theBlackBoard.theInertialSensorData.data;

  /*
  if((theMotionInfo.motion == MotionRequest::walk || theMotionInfo.motion == MotionRequest::stand ||
      (theMotionInfo.motion == MotionRequest::specialAction && theMotionInfo.specialActionRequest.specialAction == SpecialActionRequest::sitDownKeeper)) &&
     abs(safeRawAngle.x) < p.calculatedAccLimit.x && abs(safeRawAngle.y) < p.calculatedAccLimit.y)
  */
  double mode = 0;
  MODIFY("InertiaSensorFilter:mode",mode);

  double modePlot = 0;
  if(
    (theBlackBoard.theMotionStatus.currentMotion == motion::stand || theBlackBoard.theMotionStatus.currentMotion == motion::walk)
    //&& ( theBlackBoard.theSupportPolygon.mode & (SupportPolygon::DOUBLE | SupportPolygon::DOUBLE_LEFT | SupportPolygon::DOUBLE_RIGHT) )
    && (theBlackBoard.theGroundContactModel.leftGroundContact || theBlackBoard.theGroundContactModel.rightGroundContact)
    && abs(safeRawAngle.x) < p.calculatedAccLimit.x && abs(safeRawAngle.y) < p.calculatedAccLimit.y
    )
  {
    // use a modeled acceleration, if the feet are on the ground

    RotationMatrix calculatedRotation =
      Kinematics::ForwardKinematics::calcChestFeetRotation(theBlackBoard.theKinematicChain);

    Vector3<double> accGravOnly(calculatedRotation[0].z, calculatedRotation[1].z, calculatedRotation[2].z);
    accGravOnly *= -Math::g;

    PLOT("InertiaSensorFilter:accGravOnly:x", accGravOnly.x);
    PLOT("InertiaSensorFilter:accGravOnly:y", accGravOnly.y);
    PLOT("InertiaSensorFilter:accGravOnly:z", accGravOnly.z);
    modePlot = 0;

    readingUpdate(accGravOnly);
  }
  else // insert acceleration sensor values
  {
    PLOT("theCalibrationData.calibrated", theBlackBoard.theCalibrationData.calibrated);

    if(theBlackBoard.theCalibrationData.calibrated) // use only calibrated data
      readingUpdate(theBlackBoard.theAccelerometerData.data);
    else // use the aldebaran sensor as a fallback
      x.rotation = RotationMatrix(Vector3<double>(safeRawAngle.x, safeRawAngle.y, 0.0));

    modePlot = 1;
  }

  PLOT("InertiaSensorFilter:mode", modePlot);

  // fill the representation
  theInertialModel.orientation = Vector2<double>(
                                  atan2(x.rotation[1].z, x.rotation[2].z),
                                  atan2(-x.rotation[0].z, x.rotation[2].z));

  // this removes any kind of z-rotation from internal rotation
  if(theInertialModel.orientation.abs2() < 0.04 * 0.04)
    x.rotation = RotationMatrix(Vector3<double>(theInertialModel.orientation.x, theInertialModel.orientation.y, 0.0));

  // store some data for the next iteration
  lastTime = theBlackBoard.theFrameInfo.getTime();

  // plots
  PLOT("InertiaSensorFilter:orientationX", theInertialModel.orientation.x);
  PLOT("InertiaSensorFilter:orientationY", theInertialModel.orientation.y);

  return theInertialModel.orientation;
}//end update

void InertiaSensorFilter::predict(const RotationMatrix& rotationOffset)
{
  generateSigmaPoints();

  // update sigma points
  for(int i = 0; i < 5; ++i)
    sigmaPoints[i].rotation *= rotationOffset;

  // get new mean and cov
  meanOfSigmaPoints();
  covOfSigmaPoints();

  // add process noise
  cov.c[0].x += p.processCov.c[0].x;
  cov.c[1].y += p.processCov.c[1].y;
}

void InertiaSensorFilter::readingModel(const State<double>& sigmaPoint, Vector3<double>& reading)
{
  reading = Vector3<double>(sigmaPoint.rotation[0].z, sigmaPoint.rotation[1].z, sigmaPoint.rotation[2].z);
  reading *= -Math::g;
}

void InertiaSensorFilter::readingUpdate(const Vector3<double>& reading)
{
  generateSigmaPoints();

  for(int i = 0; i < 5; ++i)
    readingModel(sigmaPoints[i], sigmaReadings[i]);

  meanOfSigmaReadings();

  PLOT("InertiaSensorFilter:expectedAccX", readingMean.x);
  PLOT("InertiaSensorFilter:accX", reading.x);
  PLOT("InertiaSensorFilter:expectedAccY", readingMean.y);
  PLOT("InertiaSensorFilter:accY", reading.y);
  PLOT("InertiaSensorFilter:expectedAccZ", readingMean.z);
  PLOT("InertiaSensorFilter:accZ", reading.z);

  covOfSigmaReadingsAndSigmaPoints();
  covOfSigmaReadings();

  const Matrix2x3<double>& kalmanGain = readingsSigmaPointsCov.transpose() * (readingsCov + p.sensorCov).invert();
  const Vector2<double>& innovation = kalmanGain * (reading - readingMean);
  x += innovation;
  cov -= kalmanGain * readingsSigmaPointsCov;
}

void InertiaSensorFilter::generateSigmaPoints()
{
  cholOfCov();
  sigmaPoints[0] = x;
  sigmaPoints[1] = x + l.c[0];
  sigmaPoints[2] = x + l.c[1];
  sigmaPoints[3] = x + (-l.c[0]);
  sigmaPoints[4] = x + (-l.c[1]);
}

void InertiaSensorFilter::meanOfSigmaPoints()
{
  x = sigmaPoints[0];
  //for(int i = 0; i < 5; ++i) // ~= 0 .. inf
  for(int i = 0; i < 1; ++i)
  {
    Vector2<double> chunk((sigmaPoints[0] - x) +
                    ((sigmaPoints[1] - x) + (sigmaPoints[2] - x)) +
                    ((sigmaPoints[3] - x) + (sigmaPoints[4] - x)));
    chunk /= 5.f;
    x += chunk;
  }
}

void InertiaSensorFilter::covOfSigmaPoints()
{
  cov = tensor(sigmaPoints[0] - x) +
        (tensor(sigmaPoints[1] - x) + tensor(sigmaPoints[2] - x)) +
        (tensor(sigmaPoints[3] - x) + tensor(sigmaPoints[4] - x));
  cov *= 0.5f;
}

template <class V> InertiaSensorFilter::State<V> InertiaSensorFilter::State<V>::operator+(const Vector2<V>& value) const
{
  return State(*this) += value;
}

template <class V> InertiaSensorFilter::State<V>& InertiaSensorFilter::State<V>::operator+=(const Vector2<V>& value)
{
  rotation *= RotationMatrix(rotation.invert() * Vector3<V>(value.x, value.y, V()));
  return *this;
}

template <class V> Vector2<V> InertiaSensorFilter::State<V>::operator-(const State<V>& other) const
{
  const Vector3<V>& rotDiff(other.rotation * ((const RotationMatrix&)(other.rotation.invert() * rotation)).getAngleAxis());
  return Vector2<V>(rotDiff.x, rotDiff.y);
}

void InertiaSensorFilter::cholOfCov()
{
  // improved symmetry
  const double a11 = cov.c[0].x;
  const double a21 = (cov.c[0].y + cov.c[1].x) * 0.5f;

  const double a22 = cov.c[1].y;

  double& l11(l.c[0].x);
  double& l21(l.c[0].y);

  double& l22(l.c[1].y);

  //ASSERT(a11 >= 0.f);
  l11 = sqrt(std::max(a11, 0.0));
  if(l11 == 0.f) l11 = 0.0000000001f;
  l21 = a21 / l11;

  //ASSERT(a22 - l21 * l21 >= 0.f);
  l22 = sqrt(std::max(a22 - l21 * l21, 0.0));
  if(l22 == 0.f) l22 = 0.0000000001f;
}

void InertiaSensorFilter::meanOfSigmaReadings()
{
  readingMean = sigmaReadings[0];
  //for(int i = 0; i < 5; ++i) // ~= 0 .. inf
  for(int i = 0; i < 1; ++i)
  {
    Vector3<double> chunk((sigmaReadings[0] - readingMean) +
                    ((sigmaReadings[1] - readingMean) + (sigmaReadings[2] - readingMean)) +
                    ((sigmaReadings[3] - readingMean) + (sigmaReadings[4] - readingMean)));
    chunk /= 5.f;
    readingMean += chunk;
  }
}

void InertiaSensorFilter::covOfSigmaReadingsAndSigmaPoints()
{
  readingsSigmaPointsCov = (
    (tensor(sigmaReadings[1] - readingMean, l.c[0]) + tensor(sigmaReadings[2] - readingMean, l.c[1])) +
    (tensor(sigmaReadings[3] - readingMean, -l.c[0]) + tensor(sigmaReadings[4] - readingMean, -l.c[1])));
  readingsSigmaPointsCov *= 0.5f;
}

void InertiaSensorFilter::covOfSigmaReadings()
{
  readingsCov = (tensor(sigmaReadings[0] - readingMean) +
                 (tensor(sigmaReadings[1] - readingMean) + tensor(sigmaReadings[2] - readingMean)) +
                 (tensor(sigmaReadings[3] - readingMean) + tensor(sigmaReadings[4] - readingMean)));
  readingsCov *= 0.5f;
}
<|endoftext|>


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

#ifndef CONFIGMGR_API_ACCESSOBJECTS_HXX_
#define CONFIGMGR_API_ACCESSOBJECTS_HXX_

#include "apitreeaccess.hxx"
#include "apinodeaccess.hxx"
#include "apinodeupdate.hxx"

#include "apitreeimplobj.hxx"
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif

#include "apiserviceinfo.hxx"

namespace configmgr
{
//-----------------------------------------------------------------------------
    namespace configapi
    {
//-----------------------------------------------------------------------------
        using configuration::Tree;
        using configuration::NodeRef;

//-----------------------------------------------------------------------------
// Inner Elements
//-----------------------------------------------------------------------------

        template <class NodeClass>
        class OInnerElement : public InnerElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;

            UnoInterface*   m_pUnoThis;
            ApiTreeImpl&    m_rTree;
            NodeRef         m_aNode;
        public:
            OInnerElement(UnoInterface* pUnoThis,ApiTreeImpl& rTree, NodeRef const& aNode);
            ~OInnerElement();

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };
    //-------------------------------------------------------------------------

        typedef OInnerElement<NodeGroupInfoAccess>  OInnerGroupInfoAccess;
        typedef OInnerElement<NodeGroupAccess>      OInnerGroupUpdateAccess;
        typedef OInnerElement<NodeSetInfoAccess>    OInnerSetInfoAccess;
        typedef OInnerElement<NodeTreeSetAccess>    OInnerTreeSetUpdateAccess;
        typedef OInnerElement<NodeValueSetAccess>   OInnerValueSetUpdateAccess;

//-----------------------------------------------------------------------------
// Set Elements
//-----------------------------------------------------------------------------

        template <class NodeClass>
        class OSetElement : public SetElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;

            mutable ApiTreeImpl     m_aTree;
        public:
            OSetElement(UnoInterface* pUnoThis, configuration::TreeRef const& aTree, ApiTreeImpl& rParentTree)
            : m_aTree(pUnoThis, aTree,rParentTree)
            {}
            OSetElement(UnoInterface* pUnoThis, configuration::TreeRef const& aTree, ApiProvider& rProvider, ApiTreeImpl* pParentTree = 0)
            : m_aTree(pUnoThis, rProvider,aTree,pParentTree)
            {}

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };

    // Set Elements
    //-------------------------------------------------------------------------

        typedef OSetElement<NodeGroupInfoAccess>    OSetElementGroupInfoAccess;
        typedef OSetElement<NodeGroupAccess>        OSetElementGroupUpdateAccess;
        typedef OSetElement<NodeSetInfoAccess>      OSetElementSetInfoAccess;
        typedef OSetElement<NodeTreeSetAccess>      OSetElementTreeSetUpdateAccess;
        typedef OSetElement<NodeValueSetAccess>     OSetElementValueSetUpdateAccess;

//-----------------------------------------------------------------------------
// Root Elements
//-----------------------------------------------------------------------------

        template <class NodeClass>
        class OReadRootElement : public RootElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;
            mutable ApiRootTreeImpl     m_aRootTree;
        public:
            OReadRootElement(UnoInterface* pUnoThis, ApiProvider& rProvider, configuration::Tree const& aTree, vos::ORef< OOptions >const& _xOptions)
                : m_aRootTree(pUnoThis, rProvider,aTree, _xOptions)
            {}

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;
            virtual ApiRootTreeImpl&    getRootTree();

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };
    //-------------------------------------------------------------------------

        template <class NodeClass>
        class OUpdateRootElement : public UpdateRootElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;

            mutable ApiRootTreeImpl     m_aRootTree;
        public:
            OUpdateRootElement(UnoInterface* pUnoThis, ApiProvider& rProvider, configuration::Tree const& aTree, vos::ORef< OOptions >const& _xOptions)
            : m_aRootTree(pUnoThis, rProvider,aTree,_xOptions)
            {}

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;
            virtual ApiRootTreeImpl&    getRootTree();

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };

    // Root Elements
    //-------------------------------------------------------------------------

        typedef OReadRootElement<NodeGroupInfoAccess>   ORootElementGroupInfoAccess;
        typedef OUpdateRootElement<NodeGroupAccess>     ORootElementGroupUpdateAccess;
        typedef OReadRootElement<NodeSetInfoAccess>     ORootElementSetInfoAccess;
        typedef OUpdateRootElement<NodeTreeSetAccess>   ORootElementTreeSetUpdateAccess;
        typedef OUpdateRootElement<NodeValueSetAccess>  ORootElementValueSetUpdateAccess;

//-----------------------------------------------------------------------------
    }
}
//-----------------------------------------------------------------------------
#include "apiaccessobj.inl"
//-----------------------------------------------------------------------------

#endif // CONFIGMGR_API_ACCESSOBJECTS_HXX_
<commit_msg>INTEGRATION: CWS ooo19126 (1.10.108); FILE MERGED 2005/09/05 17:03:28 rt 1.10.108.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: apiaccessobj.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 03:05:26 $
 *
 *  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 CONFIGMGR_API_ACCESSOBJECTS_HXX_
#define CONFIGMGR_API_ACCESSOBJECTS_HXX_

#include "apitreeaccess.hxx"
#include "apinodeaccess.hxx"
#include "apinodeupdate.hxx"

#include "apitreeimplobj.hxx"
#ifndef CONFIGMGR_CONFIGNODE_HXX_
#include "noderef.hxx"
#endif

#include "apiserviceinfo.hxx"

namespace configmgr
{
//-----------------------------------------------------------------------------
    namespace configapi
    {
//-----------------------------------------------------------------------------
        using configuration::Tree;
        using configuration::NodeRef;

//-----------------------------------------------------------------------------
// Inner Elements
//-----------------------------------------------------------------------------

        template <class NodeClass>
        class OInnerElement : public InnerElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;

            UnoInterface*   m_pUnoThis;
            ApiTreeImpl&    m_rTree;
            NodeRef         m_aNode;
        public:
            OInnerElement(UnoInterface* pUnoThis,ApiTreeImpl& rTree, NodeRef const& aNode);
            ~OInnerElement();

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };
    //-------------------------------------------------------------------------

        typedef OInnerElement<NodeGroupInfoAccess>  OInnerGroupInfoAccess;
        typedef OInnerElement<NodeGroupAccess>      OInnerGroupUpdateAccess;
        typedef OInnerElement<NodeSetInfoAccess>    OInnerSetInfoAccess;
        typedef OInnerElement<NodeTreeSetAccess>    OInnerTreeSetUpdateAccess;
        typedef OInnerElement<NodeValueSetAccess>   OInnerValueSetUpdateAccess;

//-----------------------------------------------------------------------------
// Set Elements
//-----------------------------------------------------------------------------

        template <class NodeClass>
        class OSetElement : public SetElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;

            mutable ApiTreeImpl     m_aTree;
        public:
            OSetElement(UnoInterface* pUnoThis, configuration::TreeRef const& aTree, ApiTreeImpl& rParentTree)
            : m_aTree(pUnoThis, aTree,rParentTree)
            {}
            OSetElement(UnoInterface* pUnoThis, configuration::TreeRef const& aTree, ApiProvider& rProvider, ApiTreeImpl* pParentTree = 0)
            : m_aTree(pUnoThis, rProvider,aTree,pParentTree)
            {}

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };

    // Set Elements
    //-------------------------------------------------------------------------

        typedef OSetElement<NodeGroupInfoAccess>    OSetElementGroupInfoAccess;
        typedef OSetElement<NodeGroupAccess>        OSetElementGroupUpdateAccess;
        typedef OSetElement<NodeSetInfoAccess>      OSetElementSetInfoAccess;
        typedef OSetElement<NodeTreeSetAccess>      OSetElementTreeSetUpdateAccess;
        typedef OSetElement<NodeValueSetAccess>     OSetElementValueSetUpdateAccess;

//-----------------------------------------------------------------------------
// Root Elements
//-----------------------------------------------------------------------------

        template <class NodeClass>
        class OReadRootElement : public RootElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;
            mutable ApiRootTreeImpl     m_aRootTree;
        public:
            OReadRootElement(UnoInterface* pUnoThis, ApiProvider& rProvider, configuration::Tree const& aTree, vos::ORef< OOptions >const& _xOptions)
                : m_aRootTree(pUnoThis, rProvider,aTree, _xOptions)
            {}

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;
            virtual ApiRootTreeImpl&    getRootTree();

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };
    //-------------------------------------------------------------------------

        template <class NodeClass>
        class OUpdateRootElement : public UpdateRootElement, public NodeClass
        {
            static ServiceInfo const*const s_pServiceInfo;

            mutable ApiRootTreeImpl     m_aRootTree;
        public:
            OUpdateRootElement(UnoInterface* pUnoThis, ApiProvider& rProvider, configuration::Tree const& aTree, vos::ORef< OOptions >const& _xOptions)
            : m_aRootTree(pUnoThis, rProvider,aTree,_xOptions)
            {}

            virtual NodeRef             doGetNode() const;
            virtual ApiTreeImpl&        getApiTree() const;
            virtual ApiRootTreeImpl&    getRootTree();

            virtual UnoInterface*       doGetUnoInstance() const;
            virtual ServiceInfo const*  doGetServiceInfo() const;

            static ServiceInfo const* getStaticServiceInfo();
        };

    // Root Elements
    //-------------------------------------------------------------------------

        typedef OReadRootElement<NodeGroupInfoAccess>   ORootElementGroupInfoAccess;
        typedef OUpdateRootElement<NodeGroupAccess>     ORootElementGroupUpdateAccess;
        typedef OReadRootElement<NodeSetInfoAccess>     ORootElementSetInfoAccess;
        typedef OUpdateRootElement<NodeTreeSetAccess>   ORootElementTreeSetUpdateAccess;
        typedef OUpdateRootElement<NodeValueSetAccess>  ORootElementValueSetUpdateAccess;

//-----------------------------------------------------------------------------
    }
}
//-----------------------------------------------------------------------------
#include "apiaccessobj.inl"
//-----------------------------------------------------------------------------

#endif // CONFIGMGR_API_ACCESSOBJECTS_HXX_
<|endoftext|>


<commit_before>/*
  ISC License

  Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <unistd.h>

namespace fs
{
  static
  inline
  int
  fsync(const int fd)
  {
    return ::fsync(fd);
  }

  static
  inline
  int
  fdatasync(const int fd)
  {
    return ::fdatasync(fd);
  }
}
<commit_msg>check if fdatasync is available and return ENOSYS if not<commit_after>/*
  ISC License

  Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>

  Permission to use, copy, modify, and/or distribute this software for any
  purpose with or without fee is hereby granted, provided that the above
  copyright notice and this permission notice appear in all copies.

  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <errno.h>
#include <unistd.h>

namespace fs
{
  static
  inline
  int
  fsync(const int fd)
  {
    return ::fsync(fd);
  }

  static
  inline
  int
  fdatasync(const int fd)
  {
#if _POSIX_SYNCHRONIZED_IO > 0
    return ::fdatasync(fd);
#else
    return (errno=ENOSYS,-1);
#endif
  }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

#define N 10	//切り分けパターンの数
#define L 10	//もともとの金属棒の長さ

void setArrays(void);
void freeArrays(void);
void solve(void);
void backtrack(int,int,int);
void print_result(void);

struct InputSet{
	int length;
	int price;
};

struct InputSet s[N+1] =
	 {{0,0},{1,1},{2,5},{3,8},{4,9},{5,10},{6,17},{7,17},{8,20},{9,24},{10,30}};
struct InputSet *ms = NULL;	//個数制限無しのナップサック問題用に，修正した入力をここに保存
int **c = NULL;	//c[i][l]は長さlの金属棒についてi番目の切り分けパターンまで考慮したときの価格の最大値
int result[N+1] = {0};
int length = L;
int newsize;

int main(int argc,char *argv[])
{
	if(argc == 2)length = atoi(argv[1]);
	while(length > 0){
		for(int i = 0;i <= length+1;i++)printf("____ ");
		printf("\nL = %2d : result \n",length);
		setArrays();
		solve();
		print_result();
		freeArrays();
		length--;
	}
	return 0;
}

void setArrays()
{
	newsize = 0;
	for(int i = 1;i <= N;i++)newsize += (int)(length/s[i].length);
	ms = (struct InputSet *)malloc(sizeof(struct InputSet) * (newsize + 1));
	printf("NEWSIZE = %3d\n",newsize);
	ms[0] = {0,0};

	int currentIndex = 1;
	for(int i = 1;i <= N;i++){
		int count = (int)(length / s[i].length);
		for(int x = 0;x < count;x++)ms[x+currentIndex] = {s[i].length,s[i].price};
		currentIndex += count;
	}
	printf("MODIFIED INPUT IS \n[ ");
	for(int i = 0;i <= newsize;i++){
		printf("{%2d,%2d} ",ms[i].length,ms[i].price);
		if(i % length == 0)printf("\n");
	}
	printf("]\n\n");

	c = (int **)malloc(sizeof(int *) * (newsize + 1));
	for(int i = 0;i <= newsize;i++){
		c[i] = (int *)malloc(sizeof(int) * (length + 1));
	}
}

void freeArrays()
{
	free(ms);
	for(int i = 0;i <= newsize;i++){
		free(c[i]);
	}
	free(c);
}

void solve()
{
	for(int i = 0;i <= newsize;i++)c[i][0] = 0;
	for(int l = 0;l <= length;l++)c[0][l] = 0;
	for(int x=0;x<=length+1;x++)printf("**** ");printf("\n");

	for(int i = 1;i <= newsize;i++){
		for(int l = 1;l <= length;l++){
			if(ms[i].length <= l){
				if(ms[i].price + c[i-1][l-ms[i].length] > c[i-1][l]){
					c[i][l] = ms[i].price + c[i-1][l-ms[i].length];
				}else{
					c[i][l] = c[i-1][l];
				}
			}else{
				c[i][l] = c[i-1][l];
			}
		}
	}
}

void backtrack(int i, int j, int index)
{
	if(j < 1 || i < 1)return;
	while(c[i--][j] == c[i][j]);
	result[index++] = ms[++i].length;
	backtrack(i,j-ms[i].length,index);
}

void print_result()
{
	for(int i = -1;i <= newsize;i++){
		for(int l = -1;l <= length;l++){
			if(i < 0 && l < 0){
				printf("     ");
				continue;
			}else if(l < 0 ){
				printf("[%2d]  ",i);
				continue;
			}else if(i < 0){
				printf("[%2d] ",l);
				continue;
			}
			printf("%2d   ",c[i][l]);
		}
		printf("\n");
	}
	printf("\n");

	printf("MAXIMUM PRICE IS [ %2d ]\n\n",c[newsize][length]);

	backtrack(newsize,length,0);
	printf("Cutting List = [ ");
	for(int i = 0;i <= N;i++){
		if(result[i]) printf("%2d,",result[i]);
	}
	printf("]\n\n");
	for(int i = 0;i <= N;i++){
		result[i] = 0;
	}
}<commit_msg>few changes<commit_after>#include <stdio.h>
#include <stdlib.h>

#define N 10	//切り分けパターンの数
#define L 10	//もともとの金属棒の長さ

void setArrays(void);
void freeArrays(void);
void solve(void);
void backtrack(int,int,int);
void print_result(void);

struct InputSet{
	int length;
	int price;
};

struct InputSet s[N+1] =
	 {{0,0},{1,1},{2,5},{3,8},{4,9},{5,10},{6,17},{7,17},{8,20},{9,24},{10,30}};
struct InputSet *ms = NULL;	//個数制限無しのナップサック問題用に，修正した入力をここに保存
int **c = NULL;	//c[i][l]は長さlの金属棒についてi番目の切り分けパターンまで考慮したときの価格の最大値
int result[N+1] = {0};
int length = L;
int newsize;

int main(int argc,char *argv[])
{
	if(argc == 2)length = atoi(argv[1]);
	while(length > 0){
		for(int i = 0;i <= length+1;i++)printf("____ ");
		printf("\nL = %2d : result \n",length);
		setArrays();
		solve();
		backtrack(newsize,length,0);
		print_result();
		freeArrays();
		length--;
	}
	return 0;
}

void setArrays()
{
	newsize = 0;
	for(int i = 1;i <= N;i++)newsize += (int)(length/s[i].length);
	ms = (struct InputSet *)malloc(sizeof(struct InputSet) * (newsize + 1));
	printf("NEWSIZE = %3d\n",newsize);
	ms[0] = {0,0};

	int currentIndex = 1;
	for(int i = 1;i <= N;i++){
		int count = (int)(length / s[i].length);
		for(int x = 0;x < count;x++)ms[x+currentIndex] = {s[i].length,s[i].price};
		currentIndex += count;
	}
	printf("MODIFIED INPUT IS \n[ ");
	for(int i = 0;i <= newsize;i++){
		printf("{%2d,%2d} ",ms[i].length,ms[i].price);
		if(i % length == 0)printf("\n");
	}
	printf("]\n\n");

	c = (int **)malloc(sizeof(int *) * (newsize + 1));
	for(int i = 0;i <= newsize;i++){
		c[i] = (int *)malloc(sizeof(int) * (length + 1));
	}
}

void freeArrays()
{
	free(ms);
	for(int i = 0;i <= newsize;i++){
		free(c[i]);
	}
	free(c);
}

void solve()
{
	for(int i = 0;i <= newsize;i++)c[i][0] = 0;
	for(int l = 0;l <= length;l++)c[0][l] = 0;
	for(int x=0;x<=length+1;x++)printf("**** ");printf("\n");

	for(int i = 1;i <= newsize;i++){
		for(int l = 1;l <= length;l++){
			if(ms[i].length <= l){
				if(ms[i].price + c[i-1][l-ms[i].length] > c[i-1][l]){
					c[i][l] = ms[i].price + c[i-1][l-ms[i].length];
				}else{
					c[i][l] = c[i-1][l];
				}
			}else{
				c[i][l] = c[i-1][l];
			}
		}
	}
}

void backtrack(int i, int j, int index)
{
	if(j < 1 || i < 1)return;
	while(c[i--][j] == c[i][j]);
	result[index++] = ms[++i].length;
	backtrack(i,j-ms[i].length,index);
}

void print_result()
{
	for(int i = -1;i <= newsize;i++){
		for(int l = -1;l <= length;l++){
			if(i < 0 && l < 0){
				printf("     ");
				continue;
			}else if(l < 0 ){
				printf("[%2d]  ",i);
				continue;
			}else if(i < 0){
				printf("[%2d] ",l);
				continue;
			}
			printf("%2d   ",c[i][l]);
		}
		printf("\n");
	}
	printf("\n");

	printf("MAXIMUM PRICE IS [ %2d ]\n\n",c[newsize][length]);

	printf("Cutting List = [ ");
	for(int i = 0;i <= N;i++){
		if(result[i]) printf("%2d,",result[i]);
	}
	printf("]\n\n");
	for(int i = 0;i <= N;i++){
		result[i] = 0;
	}
}<|endoftext|>


<commit_before>#include <Magick++.h>
#include <iostream>
#include <math.h>
#include <list>

#define PI 3.14159265358979323846
#define DEG2RAD(DEG) ((DEG)*((PI)/(180.0)))

using namespace std;
using namespace Magick;

int WIDTH = 450;
int HEIGHT = 400;
int STEP = 1;

typedef struct branch_str
{
	// Count of all child leaves
	int totalChildren;
	int subBranches;
	branch_str **branches;
} Branch;

// Angle is measured from standard cartesian y=0, x>0 (right)
void drawBranch(list<Drawable> *drawList, Branch *branch, int startSize, int endSize, int length, int x, int y, int angle)
{
	cout << "[" << branch->subBranches << "," << branch->totalChildren << "]" << endl;
	if(startSize < 2)
	{
		startSize = 2;
	}

	if(endSize < 2)
	{
		endSize = 2;
	}

	// Calculate x-diff, y-diff & r-diff values
	int xStep = (length * cos(DEG2RAD(angle)));
	int yStep = (length * sin(DEG2RAD(angle)));
	int steps = (length / STEP);

	double xDiff = xStep/(double)steps;
	double yDiff = yStep/(double)steps;
	double rDiff = (endSize - startSize)/(2.0*steps);

	//printf("Drawing branch [size[start: %u, end: %u], length: %u, step[x: %d, y: %d]]\n",startSize, endSize,length,xStep,yStep);
	//cout << "...will take " << steps << " steps." << endl;

	// Draw branch
	drawList->push_back(DrawableFillColor("brown"));
	double radius = startSize/2.0;
	double _x = x;
	double _y = y;
	for(int i = 0; i < steps; i++)
	{
		//cout << " - step " << i << endl;
		// Draw circle
		//cout << "Drawing circle(" << (int)radius << ") at (" << _x << "," << _y << ")" << endl;
		//image.draw(DrawableCircle(_x, _y, (int)radius, (int)radius));
		drawList->push_back(DrawableCircle(_x, _y, _x, _y + (int)radius));
		_x += xDiff;
		_y += yDiff;
		radius += rDiff;
	}
	if(branch->subBranches > 0)
	{
		// Create other branches
		double aDiff = ((160/(branch->subBranches))-5+(rand()%15));
		int _angle = -190 + (rand() % 30) + aDiff*0.5;
		for(int i = 0; i < branch->subBranches; i++)
		{
			//printf("Drawing branch at angle %d\n", angle);
			double branchFraction = ((double)branch->branches[i]->totalChildren)/branch->totalChildren;
			if(branchFraction < (1/(2.0*branch->subBranches)))
			{
				branchFraction = (1/(2.0*branch->subBranches));
			}
			//drawBranch(image, branch->branches[i], rootSize*(((double)branch->branches[i]->totalChildren)/branch->totalChildren), length*((rand()%10)/10.0), _x, _y, _angle);
			drawBranch(drawList, branch->branches[i], endSize, endSize*branchFraction, length*(((rand()%400)/1000.0) + 0.55), _x, _y, _angle);
			_angle += aDiff;
		}
	}
	else if(branch->totalChildren > 0)
	{
		// Draw leaves
		drawList->push_back(DrawableFillColor("green"));
		// Draw in circle around end of branch
		int leafRadius = 11;
		double leafBuffer = 2.5;
		int leafSize = 2*(leafRadius + leafBuffer);
		if(branch->totalChildren > 1)
		{
			int radiusIncrement = leafSize + 2*leafBuffer;
			int levels = ((int)log((branch->totalChildren-1)*leafSize/radiusIncrement) + 1);
			if(levels < 1)
			{
				levels = 1;
			}
			int radius = 0;
			int totalChildCount = 0;
			int childrenAtLevel = 0;
			for(int v = 0; v < levels; v++)
			{
				radius += radiusIncrement;
				childrenAtLevel = (int)(2.0*PI*radius/leafSize);
				totalChildCount += childrenAtLevel;
				if(totalChildCount > branch->totalChildren)
				{
					childrenAtLevel = (branch->totalChildren - totalChildCount - childrenAtLevel);
				}
				double angDiv = (2*PI)/childrenAtLevel;
				double ang = 0;
				for(int i = 0; i < childrenAtLevel; i++)
				{
					int __x = _x + (radius * (((rand()%350)/1000.0) + 0.75)) * cos(ang);
					int __y = _y + (radius * (((rand()%350)/1000.0) + 0.5)) * sin(ang);
					drawList->push_back(DrawableCircle(__x, __y, __x, __y + leafRadius));
					ang += angDiv;
				}
			}
		}
		drawList->push_back(DrawableCircle(_x, _y, _x, _y + leafRadius));
		// Draw final node at center
		//if(branch->totalChildren > 0)
		//{
		//	drawList->push_back(DrawableCircle(_x, _y, _x, _y + leafRadius));
		//}
	}
}

void drawTree(Image &image, Branch *trunk, int rootSize, int height)
{
	printf("Drawing trunk\n");
	cout << endl;
	//image.fillColor("brown");

	list<Drawable> drawList;
	drawList.push_back(DrawableStrokeWidth(0));
	drawList.push_back(DrawableFillColor("brown"));

	int radius = rootSize/2;
	// Center horizontally
	int x = (WIDTH/2) - radius;
	// Start trunk at bottom of image and grow up
	int y = HEIGHT - radius;
	for(; y > HEIGHT - height - radius; y -= STEP)
	{
		// Draw circle
		//cout << "Drawing circle(" << (int)radius << ") at (" << x << "," << y << ")" << endl;
		//image.draw(DrawableCircle(x, y, radius, radius));
		drawList.push_back(DrawableCircle(x, y, x, y+radius));
	}
	// Draw all branches
	//int angle = 90;
	double aDiff = ((150/(trunk->subBranches))-10+(rand()%35));
	int angle = -170 - (rand() % 35) + aDiff*((rand()%800)/1000.0);
	for(int i = 0; i < trunk->subBranches; i++)
	{
		printf("Drawing branch at angle %d\n", angle);
		double branchFraction = ((double)trunk->branches[i]->totalChildren)/trunk->totalChildren;
		double weight = 1.0;
		double branchWeight = 1.0;
		if(branchFraction < 0.2)
		{
			branchFraction = 0.2;
			weight = 0.85;
			branchWeight = 0.35;
		}
		drawBranch(&drawList, trunk->branches[i], rootSize*branchWeight, rootSize*branchFraction, height*(((rand()%250)/1000.0)+0.5), x, y, angle*weight);
		angle += (aDiff * (((rand()%500)/1000.0) + 0.75));
	}

	image.draw(drawList);
	image.display();
}

int main(int argc,char **argv)
{
    InitializeMagick(*argv);
    srand(time(0));

    // Setup branches
    Branch *trunk = new Branch;
    trunk->totalChildren = 100;
    trunk->subBranches = 3;
    trunk->branches = (Branch**)malloc(trunk->subBranches*sizeof(Branch*));

    Branch* sub1 = new Branch;
    sub1->totalChildren = 65;
    sub1->subBranches = 4;
    trunk->branches[0] = sub1;
    sub1->branches = (Branch**)malloc(sub1->subBranches*sizeof(Branch*));
    Branch* sub11 = new Branch;
    sub11->totalChildren = 10;
    sub11->subBranches = 0;
    sub1->branches[0] = sub11;
    Branch* sub12 = new Branch;
    sub12->totalChildren = 35;
    sub12->subBranches = 2;
    sub1->branches[1] = sub12;
    sub12->branches = (Branch**)malloc(sub12->subBranches*sizeof(Branch*));
    Branch* sub121 = new Branch;
    sub121->totalChildren = 11;
    sub121->subBranches = 0;
    sub12->branches[0] = sub121;
    Branch* sub122 = new Branch;
    sub122->totalChildren = 24;
    sub122->subBranches = 0;
    sub12->branches[1] = sub122;
    Branch* sub13 = new Branch;
    sub13->totalChildren = 15;
    sub13->subBranches = 1;
    sub1->branches[2] = sub13;
    sub13->branches = (Branch**)malloc(sub13->subBranches*sizeof(Branch*));
    Branch* sub131 = new Branch;
    sub131->totalChildren = 15;
    sub131->subBranches = 0;
    sub13->branches[0] = sub131;
    Branch* sub14 = new Branch;
    sub14->totalChildren = 5;
    sub14->subBranches = 0;
    sub1->branches[3] = sub14;

    Branch* sub2 = new Branch;
    sub2->totalChildren = 35;
    sub2->subBranches = 2;
    trunk->branches[1] = sub2;
    sub2->branches = (Branch**)malloc(sub2->subBranches*sizeof(Branch*));
    Branch* sub21 = new Branch;
    sub21->totalChildren = 15;
    sub21->subBranches = 0;
    sub2->branches[0] = sub21;
    Branch* sub22 = new Branch;
    sub22->totalChildren = 20;
    sub22->subBranches = 2;
    sub2->branches[1] = sub22;
    sub22->branches = (Branch**)malloc(sub22->subBranches*sizeof(Branch*));
    Branch* sub221 = new Branch;
    sub221->totalChildren = 12;
    sub221->subBranches = 0;
    sub22->branches[0] = sub221;
    Branch* sub222 = new Branch;
    sub222->totalChildren = 8;
    sub222->subBranches = 0;
    sub22->branches[1] = sub222;
    Branch* sub3 = new Branch;
    sub3->totalChildren = 40;
    sub3->subBranches = 0;
    trunk->branches[2] = sub3;

    // Construct the image object. Seperating image construction from the
    // the read operation ensures that a failure to read the image file
    // doesn't render the image object useless.
    Image tree(Geometry(WIDTH,HEIGHT),"white");

    // Start with drawing trunk->  This method iteratively draws the
    // branches as well.
    drawTree(tree, trunk, 30, 125);

    try
    {
        // Write the image to a file
        tree.write( "out/tree.jpg" );
    }
    catch( Exception &error_ )
    {
        cout << "Caught exception: " << error_.what() << endl;
        return 1;
    }
    return 0;
}
<commit_msg>added call for git<commit_after>#include <Magick++.h>
#include <iostream>
#include <math.h>
#include <list>
#include "git.h"

#define PI 3.14159265358979323846
#define DEG2RAD(DEG) ((DEG)*((PI)/(180.0)))

using namespace std;
using namespace Magick;

int WIDTH = 450;
int HEIGHT = 400;
int STEP = 1;

typedef struct branch_str
{
	// Count of all child leaves
	int totalChildren;
	int subBranches;
	branch_str **branches;
} Branch;

// Angle is measured from standard cartesian y=0, x>0 (right)
void drawBranch(list<Drawable> *drawList, Branch *branch, int startSize, int endSize, int length, int x, int y, int angle)
{
	cout << "[" << branch->subBranches << "," << branch->totalChildren << "]" << endl;
	if(startSize < 2)
	{
		startSize = 2;
	}

	if(endSize < 2)
	{
		endSize = 2;
	}

	// Calculate x-diff, y-diff & r-diff values
	int xStep = (length * cos(DEG2RAD(angle)));
	int yStep = (length * sin(DEG2RAD(angle)));
	int steps = (length / STEP);

	double xDiff = xStep/(double)steps;
	double yDiff = yStep/(double)steps;
	double rDiff = (endSize - startSize)/(2.0*steps);

	//printf("Drawing branch [size[start: %u, end: %u], length: %u, step[x: %d, y: %d]]\n",startSize, endSize,length,xStep,yStep);
	//cout << "...will take " << steps << " steps." << endl;

	// Draw branch
	drawList->push_back(DrawableFillColor("brown"));
	double radius = startSize/2.0;
	double _x = x;
	double _y = y;
	for(int i = 0; i < steps; i++)
	{
		//cout << " - step " << i << endl;
		// Draw circle
		//cout << "Drawing circle(" << (int)radius << ") at (" << _x << "," << _y << ")" << endl;
		//image.draw(DrawableCircle(_x, _y, (int)radius, (int)radius));
		drawList->push_back(DrawableCircle(_x, _y, _x, _y + (int)radius));
		_x += xDiff;
		_y += yDiff;
		radius += rDiff;
	}
	if(branch->subBranches > 0)
	{
		// Create other branches
		double aDiff = ((160/(branch->subBranches))-5+(rand()%15));
		int _angle = -190 + (rand() % 30) + aDiff*0.5;
		for(int i = 0; i < branch->subBranches; i++)
		{
			//printf("Drawing branch at angle %d\n", angle);
			double branchFraction = ((double)branch->branches[i]->totalChildren)/branch->totalChildren;
			if(branchFraction < (1/(2.0*branch->subBranches)))
			{
				branchFraction = (1/(2.0*branch->subBranches));
			}
			//drawBranch(image, branch->branches[i], rootSize*(((double)branch->branches[i]->totalChildren)/branch->totalChildren), length*((rand()%10)/10.0), _x, _y, _angle);
			drawBranch(drawList, branch->branches[i], endSize, endSize*branchFraction, length*(((rand()%400)/1000.0) + 0.55), _x, _y, _angle);
			_angle += aDiff;
		}
	}
	else if(branch->totalChildren > 0)
	{
		// Draw leaves
		drawList->push_back(DrawableFillColor("green"));
		// Draw in circle around end of branch
		int leafRadius = 11;
		double leafBuffer = 2.5;
		int leafSize = 2*(leafRadius + leafBuffer);
		if(branch->totalChildren > 1)
		{
			int radiusIncrement = leafSize + 2*leafBuffer;
			int levels = ((int)log((branch->totalChildren-1)*leafSize/radiusIncrement) + 1);
			if(levels < 1)
			{
				levels = 1;
			}
			int radius = 0;
			int totalChildCount = 0;
			int childrenAtLevel = 0;
			for(int v = 0; v < levels; v++)
			{
				radius += radiusIncrement;
				childrenAtLevel = (int)(2.0*PI*radius/leafSize);
				totalChildCount += childrenAtLevel;
				if(totalChildCount > branch->totalChildren)
				{
					childrenAtLevel = (branch->totalChildren - totalChildCount - childrenAtLevel);
				}
				double angDiv = (2*PI)/childrenAtLevel;
				double ang = 0;
				for(int i = 0; i < childrenAtLevel; i++)
				{
					int __x = _x + (radius * (((rand()%350)/1000.0) + 0.75)) * cos(ang);
					int __y = _y + (radius * (((rand()%350)/1000.0) + 0.5)) * sin(ang);
					drawList->push_back(DrawableCircle(__x, __y, __x, __y + leafRadius));
					ang += angDiv;
				}
			}
		}
		drawList->push_back(DrawableCircle(_x, _y, _x, _y + leafRadius));
		// Draw final node at center
		//if(branch->totalChildren > 0)
		//{
		//	drawList->push_back(DrawableCircle(_x, _y, _x, _y + leafRadius));
		//}
	}
}

void drawTree(Image &image, Branch *trunk, int rootSize, int height)
{
	printf("Drawing trunk\n");
	cout << endl;
	//image.fillColor("brown");

	list<Drawable> drawList;
	drawList.push_back(DrawableStrokeWidth(0));
	drawList.push_back(DrawableFillColor("brown"));

	int radius = rootSize/2;
	// Center horizontally
	int x = (WIDTH/2) - radius;
	// Start trunk at bottom of image and grow up
	int y = HEIGHT - radius;
	for(; y > HEIGHT - height - radius; y -= STEP)
	{
		// Draw circle
		//cout << "Drawing circle(" << (int)radius << ") at (" << x << "," << y << ")" << endl;
		//image.draw(DrawableCircle(x, y, radius, radius));
		drawList.push_back(DrawableCircle(x, y, x, y+radius));
	}
	// Draw all branches
	//int angle = 90;
	double aDiff = ((150/(trunk->subBranches))-10+(rand()%35));
	int angle = -170 - (rand() % 35) + aDiff*((rand()%800)/1000.0);
	for(int i = 0; i < trunk->subBranches; i++)
	{
		printf("Drawing branch at angle %d\n", angle);
		double branchFraction = ((double)trunk->branches[i]->totalChildren)/trunk->totalChildren;
		double weight = 1.0;
		double branchWeight = 1.0;
		if(branchFraction < 0.2)
		{
			branchFraction = 0.2;
			weight = 0.85;
			branchWeight = 0.35;
		}
		drawBranch(&drawList, trunk->branches[i], rootSize*branchWeight, rootSize*branchFraction, height*(((rand()%250)/1000.0)+0.5), x, y, angle*weight);
		angle += (aDiff * (((rand()%500)/1000.0) + 0.75));
	}

	image.draw(drawList);
	image.display();
}

int main(int argc,char **argv)
{

    std::string gitDirectory = "../../";
    std::string outFile = "./outputfile.ass.outfile";
    int retStatus = getCustomGitLog(gitDirectory,outFile);

    InitializeMagick(*argv);
    srand(time(0));

    // Setup branches
    Branch *trunk = new Branch;
    trunk->totalChildren = 100;
    trunk->subBranches = 3;
    trunk->branches = (Branch**)malloc(trunk->subBranches*sizeof(Branch*));

    Branch* sub1 = new Branch;
    sub1->totalChildren = 65;
    sub1->subBranches = 4;
    trunk->branches[0] = sub1;
    sub1->branches = (Branch**)malloc(sub1->subBranches*sizeof(Branch*));
    Branch* sub11 = new Branch;
    sub11->totalChildren = 10;
    sub11->subBranches = 0;
    sub1->branches[0] = sub11;
    Branch* sub12 = new Branch;
    sub12->totalChildren = 35;
    sub12->subBranches = 2;
    sub1->branches[1] = sub12;
    sub12->branches = (Branch**)malloc(sub12->subBranches*sizeof(Branch*));
    Branch* sub121 = new Branch;
    sub121->totalChildren = 11;
    sub121->subBranches = 0;
    sub12->branches[0] = sub121;
    Branch* sub122 = new Branch;
    sub122->totalChildren = 24;
    sub122->subBranches = 0;
    sub12->branches[1] = sub122;
    Branch* sub13 = new Branch;
    sub13->totalChildren = 15;
    sub13->subBranches = 1;
    sub1->branches[2] = sub13;
    sub13->branches = (Branch**)malloc(sub13->subBranches*sizeof(Branch*));
    Branch* sub131 = new Branch;
    sub131->totalChildren = 15;
    sub131->subBranches = 0;
    sub13->branches[0] = sub131;
    Branch* sub14 = new Branch;
    sub14->totalChildren = 5;
    sub14->subBranches = 0;
    sub1->branches[3] = sub14;

    Branch* sub2 = new Branch;
    sub2->totalChildren = 35;
    sub2->subBranches = 2;
    trunk->branches[1] = sub2;
    sub2->branches = (Branch**)malloc(sub2->subBranches*sizeof(Branch*));
    Branch* sub21 = new Branch;
    sub21->totalChildren = 15;
    sub21->subBranches = 0;
    sub2->branches[0] = sub21;
    Branch* sub22 = new Branch;
    sub22->totalChildren = 20;
    sub22->subBranches = 2;
    sub2->branches[1] = sub22;
    sub22->branches = (Branch**)malloc(sub22->subBranches*sizeof(Branch*));
    Branch* sub221 = new Branch;
    sub221->totalChildren = 12;
    sub221->subBranches = 0;
    sub22->branches[0] = sub221;
    Branch* sub222 = new Branch;
    sub222->totalChildren = 8;
    sub222->subBranches = 0;
    sub22->branches[1] = sub222;
    Branch* sub3 = new Branch;
    sub3->totalChildren = 40;
    sub3->subBranches = 0;
    trunk->branches[2] = sub3;

    // Construct the image object. Seperating image construction from the
    // the read operation ensures that a failure to read the image file
    // doesn't render the image object useless.
    Image tree(Geometry(WIDTH,HEIGHT),"white");

    // Start with drawing trunk->  This method iteratively draws the
    // branches as well.
    drawTree(tree, trunk, 30, 125);

    try
    {
        // Write the image to a file
        tree.write( "out/tree.jpg" );
    }
    catch( Exception &error_ )
    {
        cout << "Caught exception: " << error_.what() << endl;
        return 1;
    }
    return 0;
}
<|endoftext|>


<commit_before>// The libMesh Finite Element Library.
// Copyright (C) 2002-2016 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// 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

// Local includes
#include "libmesh/edge_edge3.h"

namespace libMesh
{

#ifdef LIBMESH_ENABLE_AMR

const float Edge3::_embedding_matrix[2][3][3] =
  {
    // embedding matrix for child 0
    {
      // 0    1    2
      {1.0, 0.0, 0.0}, // left
      {0.0, 0.0, 1.0}, // right
      {0.375,-0.125,0.75} // middle
    },

    // embedding matrix for child 1
    {
      // 0    1    2
      {0.0, 0.0, 1.0}, // left
      {0.0, 1.0, 0.0},  // right
      {-0.125,0.375,0.75} // middle
    }
  };

#endif

bool Edge3::is_vertex(const unsigned int i) const
{
  if (i < 2)
    return true;
  return false;
}

bool Edge3::is_edge(const unsigned int i) const
{
  if (i < 2)
    return false;
  return true;
}

bool Edge3::is_face(const unsigned int ) const
{
  return false;
}

bool Edge3::is_node_on_side(const unsigned int n,
                            const unsigned int s) const
{
  libmesh_assert_less (s, 2);
  libmesh_assert_less (n, 3);
  return (s == n);
}

bool Edge3::is_node_on_edge(const unsigned int,
                            const unsigned int libmesh_dbg_var(e)) const
{
  libmesh_assert_equal_to (e, 0);
  return true;
}

bool Edge3::has_affine_map() const
{
  return (this->point(2).relative_fuzzy_equals
          ((this->point(0) + this->point(1))/2));
}

void Edge3::connectivity(const unsigned int sc,
                         const IOPackage iop,
                         std::vector<dof_id_type> & conn) const
{
  libmesh_assert_less_equal (sc, 1);
  libmesh_assert_less (sc, this->n_sub_elem());
  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);

  // Create storage
  conn.resize(2);

  switch (iop)
    {
    case TECPLOT:
      {
        switch (sc)
          {
          case 0:
            conn[0] = this->node_id(0)+1;
            conn[1] = this->node_id(2)+1;
            return;

          case 1:
            conn[0] = this->node_id(2)+1;
            conn[1] = this->node_id(1)+1;
            return;

          default:
            libmesh_error_msg("Invalid sc = " << sc);
          }
      }

    case VTK:
      {
        conn.resize(3);
        conn[0] = this->node_id(0);
        conn[1] = this->node_id(1);
        conn[2] = this->node_id(2);
        return;

        /*
          switch (sc)
          {
          case 0:
          conn[0] = this->node_id(0);
          conn[1] = this->node_id(2);

          return;

          case 1:
          conn[0] = this->node_id(2);
          conn[1] = this->node_id(1);

          return;

          default:
          libmesh_error_msg("Invalid sc = " << sc);
          }
        */
      }

    default:
      libmesh_error_msg("Unsupported IO package " << iop);
    }
}

std::pair<unsigned short int, unsigned short int>
Edge3::second_order_child_vertex (const unsigned int) const
{
  return std::pair<unsigned short int, unsigned short int>(0,0);
}

Real Edge3::volume () const
{
  // Finding the (exact) length of a general quadratic element
  // is a surprisingly complicated formula.
  Point A = this->point(0) + this->point(1) - 2*this->point(2);
  Point B = (this->point(1) - this->point(0))/2;

  const Real a = A.norm_sq();
  const Real b = 2.*(A*B);
  const Real c = B.norm_sq();

  // Degenerate straight line case
  if (a < TOLERANCE*TOLERANCE*TOLERANCE)
    return (this->point(1) - this->point(0)).norm();

  const Real ba=b/a;
  const Real ca=c/a;

  libmesh_assert (1.-ba+ca>0.);

  const Real s1 = std::sqrt(1. - ba + ca);
  const Real s2 = std::sqrt(1. + ba + ca);

  return 0.5*std::sqrt(a)*((1.-0.5*ba)*s1 +
                           (1.+0.5*ba)*s2 +
                           (ca - 0.25*ba*ba)*std::log( (1.-0.5*ba+s1)/(-1.-0.5*ba+s2) )
                           );
}

dof_id_type Edge3::key () const
{
  return this->compute_key(this->node_id(2));
}

} // namespace libMesh
<commit_msg>Loosen tolerance on straight-line check in Edge3::volume().<commit_after>// The libMesh Finite Element Library.
// Copyright (C) 2002-2016 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// 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

// Local includes
#include "libmesh/edge_edge3.h"

namespace libMesh
{

#ifdef LIBMESH_ENABLE_AMR

const float Edge3::_embedding_matrix[2][3][3] =
  {
    // embedding matrix for child 0
    {
      // 0    1    2
      {1.0, 0.0, 0.0}, // left
      {0.0, 0.0, 1.0}, // right
      {0.375,-0.125,0.75} // middle
    },

    // embedding matrix for child 1
    {
      // 0    1    2
      {0.0, 0.0, 1.0}, // left
      {0.0, 1.0, 0.0},  // right
      {-0.125,0.375,0.75} // middle
    }
  };

#endif

bool Edge3::is_vertex(const unsigned int i) const
{
  if (i < 2)
    return true;
  return false;
}

bool Edge3::is_edge(const unsigned int i) const
{
  if (i < 2)
    return false;
  return true;
}

bool Edge3::is_face(const unsigned int ) const
{
  return false;
}

bool Edge3::is_node_on_side(const unsigned int n,
                            const unsigned int s) const
{
  libmesh_assert_less (s, 2);
  libmesh_assert_less (n, 3);
  return (s == n);
}

bool Edge3::is_node_on_edge(const unsigned int,
                            const unsigned int libmesh_dbg_var(e)) const
{
  libmesh_assert_equal_to (e, 0);
  return true;
}

bool Edge3::has_affine_map() const
{
  return (this->point(2).relative_fuzzy_equals
          ((this->point(0) + this->point(1))/2));
}

void Edge3::connectivity(const unsigned int sc,
                         const IOPackage iop,
                         std::vector<dof_id_type> & conn) const
{
  libmesh_assert_less_equal (sc, 1);
  libmesh_assert_less (sc, this->n_sub_elem());
  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);

  // Create storage
  conn.resize(2);

  switch (iop)
    {
    case TECPLOT:
      {
        switch (sc)
          {
          case 0:
            conn[0] = this->node_id(0)+1;
            conn[1] = this->node_id(2)+1;
            return;

          case 1:
            conn[0] = this->node_id(2)+1;
            conn[1] = this->node_id(1)+1;
            return;

          default:
            libmesh_error_msg("Invalid sc = " << sc);
          }
      }

    case VTK:
      {
        conn.resize(3);
        conn[0] = this->node_id(0);
        conn[1] = this->node_id(1);
        conn[2] = this->node_id(2);
        return;

        /*
          switch (sc)
          {
          case 0:
          conn[0] = this->node_id(0);
          conn[1] = this->node_id(2);

          return;

          case 1:
          conn[0] = this->node_id(2);
          conn[1] = this->node_id(1);

          return;

          default:
          libmesh_error_msg("Invalid sc = " << sc);
          }
        */
      }

    default:
      libmesh_error_msg("Unsupported IO package " << iop);
    }
}

std::pair<unsigned short int, unsigned short int>
Edge3::second_order_child_vertex (const unsigned int) const
{
  return std::pair<unsigned short int, unsigned short int>(0,0);
}

Real Edge3::volume () const
{
  // Finding the (exact) length of a general quadratic element
  // is a surprisingly complicated formula.
  Point A = this->point(0) + this->point(1) - 2*this->point(2);
  Point B = (this->point(1) - this->point(0))/2;

  const Real a = A.norm_sq();
  const Real b = 2.*(A*B);
  const Real c = B.norm_sq();

  // Degenerate straight line case
  if (a < TOLERANCE*TOLERANCE)
    return (this->point(1) - this->point(0)).norm();

  const Real ba=b/a;
  const Real ca=c/a;

  libmesh_assert (1.-ba+ca>0.);

  const Real s1 = std::sqrt(1. - ba + ca);
  const Real s2 = std::sqrt(1. + ba + ca);

  Real log_term = (1. - 0.5*ba + s1) / (-1. - 0.5*ba + s2);
  libmesh_assert(!libmesh_isnan(log_term) && log_term > 0.);

  return 0.5*std::sqrt(a)*((1.-0.5*ba)*s1 +
                           (1.+0.5*ba)*s2 +
                           (ca - 0.25*ba*ba)*std::log(log_term)
                           );
}

dof_id_type Edge3::key () const
{
  return this->compute_key(this->node_id(2));
}

} // namespace libMesh
<|endoftext|>


<commit_before>/*******************************************************************************
 * Copyright (c) 2017 Nicola Del Gobbo
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the license at http://www.apache.org/licenses/LICENSE-2.0
 *
 * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
 * IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 * MERCHANTABLITY OR NON-INFRINGEMENT.
 *
 * See the Apache Version 2.0 License for specific language governing
 * permissions and limitations under the License.
 *
 * Contributors - initial API implementation:
 * Nicola Del Gobbo <nicoladelgobbo@gmail.com>
 * Mauro Doganieri <mauro.doganieri@gmail.com>
 ******************************************************************************/

#include "ghostscript4js.h"

// Lifeclycle management for the Ghostscript instance
class GhostscriptManager
{
  private:
    void *minst;
    int workers;
    mutex gs;
    static bool exists;
    static GhostscriptManager *instance;
    GhostscriptManager()
    {
        minst = NULL;
        workers = 0;
    }
    void Init();
    void Destroy();
    void Exit();
    void IncreaseWorkers();
    void DecreaseWorkers();

  public:
    static GhostscriptManager *GetInstance();
    ~GhostscriptManager()
    {
        exists = false;
    };
    void Execute(int gsargc, char *gsargv[]);
};

bool GhostscriptManager::exists = false;
GhostscriptManager *GhostscriptManager::instance = NULL;
// Static method that create or simple return the instance of the GhostscriptManager
// following the singleton design pattern
GhostscriptManager *GhostscriptManager::GetInstance()
{
    if (!exists)
    {
        instance = new GhostscriptManager();
        exists = true;
        return instance;
    }
    else
    {
        return instance;
    }
}

// Init is an implementation of gsapi_new_instance.
// It returns a global static instance of Ghostscript.
// i.e. Do not call init more than once, otherwise an error will be returned.
void GhostscriptManager::Init()
{
    int code = 0;
    code = gsapi_new_instance(&minst, NULL);
    if (code < 0)
    {
        throw "Sorry error happened creating Ghostscript instance. Error code: " + to_string(code);
    }
    gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
    code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
    if (code < 0)
    {
        throw "Sorry error happened in setting the encoding for Ghostscript interpreter. Error code: " + to_string(code);
    }
}

// Execute is an implementation of gsapi_init_with_args.
// It initialises the Ghostscript interpreter given a set of arguments.
void GhostscriptManager::Execute(int gsargc, char *gsargv[])
{
    lock_guard<mutex> lk(gs);
    if (workers == 0)
    {
        Init();
    }
    IncreaseWorkers();
    int code = 0;
    code = gsapi_init_with_args(minst, gsargc, gsargv);
    if (code < 0 && code != gs_error_Quit)
    {
        throw "Sorry error happened executing Ghostscript command. Error code: " + to_string(code);
    }
    DecreaseWorkers();
    if (workers == 0)
    {
        Exit();
        Destroy();
    }
}

// Exit is an implementation of gsapi_exit.
// It exits the Ghostscript interpreter.
// It must be called if init has been called, and just before destroy.
void GhostscriptManager::Exit()
{
    int code = 0;
    code = gsapi_exit(minst);
    if (code < 0 && code != gs_error_Quit)
    {
        throw "Sorry error happened during the exit from the Ghostscript interpreter. Error code: " + to_string(code);
    }
}

// Destroy is an implementation of gsapi_delete_instance.
// It destroys a global static instance of Ghostscript.
// It should be called only after exit has been called if init has been called.
void GhostscriptManager::Destroy()
{
    gsapi_delete_instance(minst);
}

// IncreaseWorkers add 1 worker to the total workers on the system.
void GhostscriptManager::IncreaseWorkers()
{
    workers += 1;
}

// DecreaseWorkers substract 1 worker to the total workers on the system.
void GhostscriptManager::DecreaseWorkers()
{
    workers -= 1;
}

class GhostscriptWorker : public Napi::AsyncWorker
{
  public:
    GhostscriptWorker(Napi::Function& callback, vector<string> explodedCmd)
        : Napi::AsyncWorker(callback), explodedCmd(explodedCmd) {}
    ~GhostscriptWorker() {}

    void Execute()
    {
        int gsargc = static_cast<int>(explodedCmd.size());
        char **gsargv = new char *[gsargc];
        for (int i = 0; i < gsargc; i++)
        {
            gsargv[i] = (char *)explodedCmd[i].c_str();
        }
        try
        {
            GhostscriptManager *gm = GhostscriptManager::GetInstance();
            gm->Execute(gsargc, gsargv);
            delete[] gsargv;

        }
        catch (exception &e)
        {
            delete[] gsargv;
            SetError(Napi::String::New(Env(), e.what()));
        }
    }

    void OnOk()
    {
        Napi::HandleScope scope(Env());
        Callback().Call({Env().Null()});
    }

  private:
    vector<string> explodedCmd;
};

Napi::Value Version(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    Napi::Object obj = Napi::Object::New(env);
    gsapi_revision_t r;
    int res = gsapi_revision(&r, sizeof(r));
    if (res == 0) {
        obj["product"] = Napi::String::New(env, r.product);
        obj["copyright"] = Napi::String::New(env, r.copyright);
        obj["revision"] = Napi::Number::New(env, r.revision);
        obj["revisiondate"] = Napi::Number::New(env, r.revisiondate);
    } else {
        std::stringstream msg;
        msg << "Sorry error happened retrieving Ghostscript version info. Error code: " << res;
        throw Napi::Error::New(env, msg.str());
    }
    return obj;
}

vector<string> ConvertArguments(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    if (info.Length() < 1)
    {
        throw Napi::Error::New(env, "Sorry method requires 1 argument that represent the Ghostscript command.");
    }
    if (!info[0].IsString() && !info[0].IsArray())
    {
        throw Napi::Error::New(env, "Sorry method's argument should be a string or an array of strings");
    }
    vector<string> explodedCmd;
    if (info[0].IsString())
    {
        string RAWcmd = info[0].As<Napi::String>().Utf8Value();
        istringstream iss(RAWcmd);
        for (string RAWcmd; iss >> RAWcmd;)
            explodedCmd.push_back(RAWcmd);
    }
    if (info[0].IsArray())
    {
        Napi::Array array = info[0].As<Napi::Array>();
        for (uint32_t i = 0; i < array.Length(); i++)
        {
            Napi::Value value = array[i];
            if (!value.IsString())
            {
                throw Napi::Error::New(env, "Sorry method's argument should be a string or an array of strings");
            }
            string RAWcmd = value.As<Napi::String>().Utf8Value();
            explodedCmd.push_back(RAWcmd);
        }
    }
    return explodedCmd;
}

void Execute(const Napi::CallbackInfo& info) {
    vector<string> explodedCmd = ConvertArguments(info);
    Napi::Function callback = info[1].As<Napi::Function>();
    GhostscriptWorker* gs = new GhostscriptWorker(callback, explodedCmd);
    gs->Queue();
}

void ExecuteSync(const Napi::CallbackInfo& info)
{
    Napi::Env env = info.Env();
    vector<string> explodedCmd = ConvertArguments(info);
    int gsargc = static_cast<int>(explodedCmd.size());
    char **gsargv = new char *[gsargc];
    for (int i = 0; i < gsargc; i++)
    {
        gsargv[i] = (char *)explodedCmd[i].c_str();
    }
    try
    {
        GhostscriptManager *gm = GhostscriptManager::GetInstance();
        gm->Execute(gsargc, gsargv);
        delete[] gsargv;
    }
    catch (exception &e)
    {
        delete[] gsargv;
        throw Napi::Error::New(env, e.what());
    }
}

//////////////////////////// INIT & CONFIG MODULE //////////////////////////////

Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set(Napi::String::New(env, "version"), Napi::Function::New(env, Version));
    exports.Set(Napi::String::New(env, "execute"), Napi::Function::New(env, Execute));
    exports.Set(Napi::String::New(env, "executeSync"), Napi::Function::New(env, ExecuteSync));
    return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

////////////////////////////////////////////////////////////////////////////////<commit_msg>Fix exception handling<commit_after>/*******************************************************************************
 * Copyright (c) 2017 Nicola Del Gobbo
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the license at http://www.apache.org/licenses/LICENSE-2.0
 *
 * THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
 * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
 * IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
 * MERCHANTABLITY OR NON-INFRINGEMENT.
 *
 * See the Apache Version 2.0 License for specific language governing
 * permissions and limitations under the License.
 *
 * Contributors - initial API implementation:
 * Nicola Del Gobbo <nicoladelgobbo@gmail.com>
 * Mauro Doganieri <mauro.doganieri@gmail.com>
 ******************************************************************************/

#include "ghostscript4js.h"

// Lifeclycle management for the Ghostscript instance
class GhostscriptManager
{
  private:
    void *minst;
    int workers;
    mutex gs;
    static bool exists;
    static GhostscriptManager *instance;
    GhostscriptManager()
    {
        minst = NULL;
        workers = 0;
    }
    void Init();
    void Destroy();
    void Exit();
    void IncreaseWorkers();
    void DecreaseWorkers();

  public:
    static GhostscriptManager *GetInstance();
    ~GhostscriptManager()
    {
        exists = false;
    };
    void Execute(int gsargc, char *gsargv[]);
};

bool GhostscriptManager::exists = false;
GhostscriptManager *GhostscriptManager::instance = NULL;
// Static method that create or simple return the instance of the GhostscriptManager
// following the singleton design pattern
GhostscriptManager *GhostscriptManager::GetInstance()
{
    if (!exists)
    {
        instance = new GhostscriptManager();
        exists = true;
        return instance;
    }
    else
    {
        return instance;
    }
}

// Init is an implementation of gsapi_new_instance.
// It returns a global static instance of Ghostscript.
// i.e. Do not call init more than once, otherwise an error will be returned.
void GhostscriptManager::Init()
{
    int code = 0;
    code = gsapi_new_instance(&minst, NULL);
    if (code < 0)
    {
        throw std::runtime_error("Sorry error happened creating Ghostscript instance. Error code: " + to_string(code));
    }
    gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
    code = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
    if (code < 0)
    {
        throw std::runtime_error("Sorry error happened in setting the encoding for Ghostscript interpreter. Error code: " + to_string(code));
    }
}

// Execute is an implementation of gsapi_init_with_args.
// It initialises the Ghostscript interpreter given a set of arguments.
void GhostscriptManager::Execute(int gsargc, char *gsargv[])
{
    lock_guard<mutex> lk(gs);
    if (workers == 0)
    {
        Init();
    }
    IncreaseWorkers();
    int code = 0;
    code = gsapi_init_with_args(minst, gsargc, gsargv);
    if (code < 0 && code != gs_error_Quit)
    {
        throw std::runtime_error("Sorry error happened executing Ghostscript command. Error code: " + to_string(code));
    }
    DecreaseWorkers();
    if (workers == 0)
    {
        Exit();
        Destroy();
    }
}

// Exit is an implementation of gsapi_exit.
// It exits the Ghostscript interpreter.
// It must be called if init has been called, and just before destroy.
void GhostscriptManager::Exit()
{
    int code = 0;
    code = gsapi_exit(minst);
    if (code < 0 && code != gs_error_Quit)
    {
        throw std::runtime_error("Sorry error happened during the exit from the Ghostscript interpreter. Error code: " + to_string(code));
    }
}

// Destroy is an implementation of gsapi_delete_instance.
// It destroys a global static instance of Ghostscript.
// It should be called only after exit has been called if init has been called.
void GhostscriptManager::Destroy()
{
    gsapi_delete_instance(minst);
}

// IncreaseWorkers add 1 worker to the total workers on the system.
void GhostscriptManager::IncreaseWorkers()
{
    workers += 1;
}

// DecreaseWorkers substract 1 worker to the total workers on the system.
void GhostscriptManager::DecreaseWorkers()
{
    workers -= 1;
}

class GhostscriptWorker : public Napi::AsyncWorker
{
  public:
    GhostscriptWorker(Napi::Function& callback, vector<string> explodedCmd)
        : Napi::AsyncWorker(callback), explodedCmd(explodedCmd) {}
    ~GhostscriptWorker() {}

    void Execute()
    {
        int gsargc = static_cast<int>(explodedCmd.size());
        char **gsargv = new char *[gsargc];
        for (int i = 0; i < gsargc; i++)
        {
            gsargv[i] = (char *)explodedCmd[i].c_str();
        }
        try
        {
            GhostscriptManager *gm = GhostscriptManager::GetInstance();
            gm->Execute(gsargc, gsargv);
            delete[] gsargv;
        }
        catch (exception &e)
        {
            delete[] gsargv;
            SetError(e.what());
        }
    }

    void OnOk()
    {
        Napi::HandleScope scope(Env());
        Callback().Call({Env().Null()});
    }

  private:
    vector<string> explodedCmd;
};

Napi::Value Version(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    Napi::Object obj = Napi::Object::New(env);
    gsapi_revision_t r;
    int res = gsapi_revision(&r, sizeof(r));
    if (res == 0) {
        obj["product"] = Napi::String::New(env, r.product);
        obj["copyright"] = Napi::String::New(env, r.copyright);
        obj["revision"] = Napi::Number::New(env, r.revision);
        obj["revisiondate"] = Napi::Number::New(env, r.revisiondate);
    } else {
        std::stringstream msg;
        msg << "Sorry error happened retrieving Ghostscript version info. Error code: " << res;
        throw Napi::Error::New(env, msg.str());
    }
    return obj;
}

vector<string> ConvertArguments(const Napi::CallbackInfo& info) {
    Napi::Env env = info.Env();
    if (info.Length() < 1)
    {
        throw Napi::Error::New(env, "Sorry method requires 1 argument that represent the Ghostscript command.");
    }
    if (!info[0].IsString() && !info[0].IsArray())
    {
        throw Napi::Error::New(env, "Sorry method's argument should be a string or an array of strings");
    }
    vector<string> explodedCmd;
    if (info[0].IsString())
    {
        string RAWcmd = info[0].As<Napi::String>().Utf8Value();
        istringstream iss(RAWcmd);
        for (string RAWcmd; iss >> RAWcmd;)
            explodedCmd.push_back(RAWcmd);
    }
    if (info[0].IsArray())
    {
        Napi::Array array = info[0].As<Napi::Array>();
        for (uint32_t i = 0; i < array.Length(); i++)
        {
            Napi::Value value = array[i];
            if (!value.IsString())
            {
                throw Napi::Error::New(env, "Sorry method's argument should be a string or an array of strings");
            }
            string RAWcmd = value.As<Napi::String>().Utf8Value();
            explodedCmd.push_back(RAWcmd);
        }
    }
    return explodedCmd;
}

void Execute(const Napi::CallbackInfo& info) {
    vector<string> explodedCmd = ConvertArguments(info);
    Napi::Function callback = info[1].As<Napi::Function>();
    GhostscriptWorker* gs = new GhostscriptWorker(callback, explodedCmd);
    gs->Queue();
}

void ExecuteSync(const Napi::CallbackInfo& info)
{
    Napi::Env env = info.Env();
    vector<string> explodedCmd = ConvertArguments(info);
    int gsargc = static_cast<int>(explodedCmd.size());
    char **gsargv = new char *[gsargc];
    for (int i = 0; i < gsargc; i++)
    {
        gsargv[i] = (char *)explodedCmd[i].c_str();
    }
    try
    {
        GhostscriptManager *gm = GhostscriptManager::GetInstance();
        gm->Execute(gsargc, gsargv);
        delete[] gsargv;
    }
    catch (exception &e)
    {
        delete[] gsargv;
        throw Napi::Error::New(env, e.what());
    }
}

//////////////////////////// INIT & CONFIG MODULE //////////////////////////////

Napi::Object Init(Napi::Env env, Napi::Object exports) {
    exports.Set(Napi::String::New(env, "version"), Napi::Function::New(env, Version));
    exports.Set(Napi::String::New(env, "execute"), Napi::Function::New(env, Execute));
    exports.Set(Napi::String::New(env, "executeSync"), Napi::Function::New(env, ExecuteSync));
    return exports;
}

NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)

////////////////////////////////////////////////////////////////////////////////<|endoftext|>