<commit_before>
// Copyright LAAS-CNRS, 2014

// This file is originally copied from metapod/tools/spatial/lti.hh.
// Authors: Olivier Stasse (LAAS, CNRS) and Sébastien Barthélémy (Aldebaran Robotics)
// The file was modified in pinocchio by Nicolas Mansard (LAAS, CNRS)

// metapod is free software, distributed under the terms of the GNU Lesser
// General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

#ifndef __se3__symmetric3_hpp__
#define __se3__symmetric3_hpp__

#include <ostream>

namespace se3
{

  template<typename _Scalar, int _Options>
  class Symmetric3Tpl
  {
  public:
    typedef _Scalar Scalar;
    enum { Options = _Options };
    typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
    typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
    typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
    typedef Eigen::Matrix<Scalar,2,2,Options> Matrix2;
    typedef Eigen::Matrix<Scalar,3,2,Options> Matrix32;

  public:
    Symmetric3Tpl(): data_() {}
    template<typename Sc,int N,int Opt>
    explicit Symmetric3Tpl(const Eigen::Matrix<Sc,N,N,Opt> & I)
    {
      assert( (I.rows()==3)&&(I.cols()==3) );
      assert( (I-I.transpose()).isMuchSmallerThan(I) );
      data_(0) = I(0,0);
      data_(1) = I(1,0); data_(2) = I(1,1);
      data_(3) = I(2,0); data_(4) = I(2,1); data_(5) = I(2,2);
    }
    explicit Symmetric3Tpl(const Eigen::MatrixBase<Matrix3> &I)
    {
      assert( (I-I.transpose()).isMuchSmallerThan(I) );
      data_(0) = I(0,0);
      data_(1) = I(1,0); data_(2) = I(1,1);
      data_(3) = I(2,0); data_(4) = I(2,1); data_(5) = I(2,2);
    }
    explicit Symmetric3Tpl(const Vector6 &I) : data_(I) {}
    Symmetric3Tpl(const double & a0,const double & a1,const double & a2,
		  const double & a3,const double & a4,const double & a5)
    { data_ << a0,a1,a2,a3,a4,a5; }

    static Symmetric3Tpl Zero()     { return Symmetric3Tpl(Vector6::Zero()  );  }
    static Symmetric3Tpl Random()   { return Symmetric3Tpl(Vector6::Random().eval());  }
    static Symmetric3Tpl Identity() { return Symmetric3Tpl( 1, 0, 1, 0, 0, 1);  }

    /* Requiered by Inertia::operator== */
    bool operator== (const Symmetric3Tpl & S2 ) { return data_ == S2.data_; }

    struct SkewSquare
    {
      const Vector3 & v;
      SkewSquare( const Vector3 & v ) : v(v) {}
      operator Symmetric3Tpl () const
      {
	const double & x = v[0], & y = v[1], & z = v[2];
	return Symmetric3Tpl( -y*y-z*z,
			      x*y    ,  -x*x-z*z,
			      x*z    ,   y*z    ,  -x*x-y*y );
      }
    }; // struct SkewSquare
    Symmetric3Tpl operator- (const SkewSquare & v) const
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      return Symmetric3Tpl( data_[0]+y*y+z*z,
			    data_[1]-x*y    ,  data_[2]+x*x+z*z,
			    data_[3]-x*z    ,  data_[4]-y*z    ,  data_[5]+x*x+y*y );
    }
    Symmetric3Tpl& operator-= (const SkewSquare & v)
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      data_[0]+=y*y+z*z;
      data_[1]-=x*y    ;  data_[2]+=x*x+z*z;
      data_[3]-=x*z    ;  data_[4]-=y*z    ;  data_[5]+=x*x+y*y;
      return *this;
    }

    struct AlphaSkewSquare
    {
      const double & m;  const Vector3 & v;
      AlphaSkewSquare( const double & m, const SkewSquare & v ) : m(m),v(v.v) {}
      operator Symmetric3Tpl () const
      {
	const double & x = v[0], & y = v[1], & z = v[2];
	return Symmetric3Tpl( -m*(y*y+z*z),
			       m* x*y     ,  -m*(x*x+z*z),
			       m* x*z     ,   m* y*z     ,  -m*(x*x+y*y) );
      }
    };
    friend AlphaSkewSquare operator* (const double & m, const SkewSquare & sk )
    { return AlphaSkewSquare(m,sk); }
    Symmetric3Tpl operator- (const AlphaSkewSquare & v) const
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      return Symmetric3Tpl( data_[0]+v.m*(y*y+z*z),
			    data_[1]-v.m* x*y     ,  data_[2]+v.m*(x*x+z*z),
			    data_[3]-v.m* x*z     ,  data_[4]-v.m* y*z     ,  data_[5]+v.m*(x*x+y*y) );
    }
    Symmetric3Tpl& operator-= (const AlphaSkewSquare & v)
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      data_[0]+=v.m*(y*y+z*z);
      data_[1]-=v.m* x*y     ;  data_[2]+=v.m*(x*x+z*z);
      data_[3]-=v.m* x*z     ;  data_[4]-=v.m* y*z     ;  data_[5]+=v.m*(x*x+y*y);
      return *this;
    }

    const Vector6 & data () const {return data_;}
    Vector6 & data () {return data_;}

    // static Symmetric3Tpl SkewSq( const Vector3 & v )
    // {
    //   const double & x = v[0], & y = v[1], & z = v[2];
    //   return Symmetric3Tpl( -y*y-z*z,
    // 			    x*y    ,  -x*x-z*z,
    // 			    x*z    ,   y*z    ,  -x*x-y*y );
    // }

    /* Shoot a positive definite matrix. */
    static Symmetric3Tpl RandomPositive()
    {
      double
	a = double(std::rand())/RAND_MAX*2.0-1.0,
	b = double(std::rand())/RAND_MAX*2.0-1.0,
	c = double(std::rand())/RAND_MAX*2.0-1.0,
	d = double(std::rand())/RAND_MAX*2.0-1.0,
	e = double(std::rand())/RAND_MAX*2.0-1.0,
	f = double(std::rand())/RAND_MAX*2.0-1.0;
      return Symmetric3Tpl(a*a+b*b+d*d,
			   a*b+b*c+d*e, b*b+c*c+e*e,
			   a*d+b*e+d*f, b*d+c*e+e*f,  d*d+e*e+f*f );
    }

    Matrix3 matrix() const
    {
      Matrix3 res;
      res(0,0) = data_(0); res(0,1) = data_(1); res(0,2) = data_(3);
      res(1,0) = data_(1); res(1,1) = data_(2); res(1,2) = data_(4);
      res(2,0) = data_(3); res(2,1) = data_(4); res(2,2) = data_(5);
      return res;
    }
    operator Matrix3 () const { return matrix(); }

    Symmetric3Tpl operator+(const Symmetric3Tpl & s2) const
    {
      return Symmetric3Tpl((data_+s2.data_).eval());
    }

    Symmetric3Tpl & operator+=(const Symmetric3Tpl & s2)
    {
      data_ += s2.data_; return *this;
    }

    Vector3 operator*(const Vector3 &v) const
    {
      return Vector3(
		     data_(0) * v(0) + data_(1) * v(1) + data_(3) * v(2),
		     data_(1) * v(0) + data_(2) * v(1) + data_(4) * v(2),
		     data_(3) * v(0) + data_(4) * v(1) + data_(5) * v(2)
		     );
    }

    // Matrix3 operator*(const Matrix3 &a) const
    // {
    //   Matrix3 r;
    //   for(unsigned int i=0; i<3; ++i)
    //     {
    //       r(0,i) = data_(0) * a(0,i) + data_(1) * a(1,i) + data_(3) * a(2,i);
    //       r(1,i) = data_(1) * a(0,i) + data_(2) * a(1,i) + data_(4) * a(2,i);
    //       r(2,i) = data_(3) * a(0,i) + data_(4) * a(1,i) + data_(5) * a(2,i);
    //     }
    //   return r;
    // }

    const Scalar& operator()(const int &i,const int &j) const
    {
      return ((i!=2)&&(j!=2)) ? data_[i+j] : data_[i+j+1];
    }

    Symmetric3Tpl operator-(const Matrix3 &S) const
    {
      assert( (S-S.transpose()).isMuchSmallerThan(S) );
      return Symmetric3Tpl( data_(0)-S(0,0),
			    data_(1)-S(1,0), data_(2)-S(1,1),
			    data_(3)-S(2,0), data_(4)-S(2,1), data_(5)-S(2,2) );
    }

    Symmetric3Tpl operator+(const Matrix3 &S) const
    {
      assert( (S-S.transpose()).isMuchSmallerThan(S) );
      return Symmetric3Tpl( data_(0)+S(0,0),
			    data_(1)+S(1,0), data_(2)+S(1,1),
			    data_(3)+S(2,0), data_(4)+S(2,1), data_(5)+S(2,2) );
    }

    /* --- Symmetric R*S*R' and R'*S*R products --- */
  public: //private:

    /** \brief Computes L for a symmetric matrix A.
     */
    Matrix32  decomposeltI() const
    {
      Matrix32 L;
      L <<
	data_(0) - data_(5),    data_(1),
	data_(1),              data_(2) - data_(5),
	2*data_(3),            data_(4) + data_(4);
      return L;
    }

    /* R*S*R' */
    template<typename D>
    Symmetric3Tpl rotate(const Eigen::MatrixBase<D> & R) const
    {
      assert( (R.cols()==3) && (R.rows()==3) );
      assert( (R.transpose()*R).isApprox(Matrix3::Identity()) );

      Symmetric3Tpl Sres;

      // 4 a
      const Matrix32 L( decomposeltI() );

      // Y = R' L   ===> (12 m + 8 a)
      const Matrix2 Y( R.template block<2,3>(1,0) * L );

      // Sres= Y R  ===> (16 m + 8a)
      Sres.data_(1) = Y(0,0)*R(0,0) + Y(0,1)*R(0,1);
      Sres.data_(2) = Y(0,0)*R(1,0) + Y(0,1)*R(1,1);
      Sres.data_(3) = Y(1,0)*R(0,0) + Y(1,1)*R(0,1);
      Sres.data_(4) = Y(1,0)*R(1,0) + Y(1,1)*R(1,1);
      Sres.data_(5) = Y(1,0)*R(2,0) + Y(1,1)*R(2,1);

      // r=R' v ( 6m + 3a)
      const Vector3 r( -R(0,0)*data_(4) + R(0,1)*data_(3),
		       -R(1,0)*data_(4) + R(1,1)*data_(3),
		       -R(2,0)*data_(4) + R(2,1)*data_(3) );

      // Sres_11 (3a)
      Sres.data_(0) = L(0,0) + L(1,1) - Sres.data_(2) - Sres.data_(5);

      // Sres + D + (Ev)x ( 9a)
      Sres.data_(0) += data_(5);
      Sres.data_(1) += r(2);    Sres.data_(2)+= data_(5);
      Sres.data_(3) +=-r(1);    Sres.data_(4)+=    r(0); Sres.data_(5) += data_(5);

      return Sres;
    }

  private:

    Vector6 data_;
  };

  typedef Symmetric3Tpl<double,0> Symmetric3;

} // namespace se3

#endif // ifndef __se3__symmetric3_hpp__

<commit_msg>[C++] Add setter for the class symmetric3<commit_after>
// Copyright LAAS-CNRS, 2014

// This file is originally copied from metapod/tools/spatial/lti.hh.
// Authors: Olivier Stasse (LAAS, CNRS) and Sébastien Barthélémy (Aldebaran Robotics)
// The file was modified in pinocchio by Nicolas Mansard (LAAS, CNRS)

// metapod is free software, distributed under the terms of the GNU Lesser
// General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

#ifndef __se3__symmetric3_hpp__
#define __se3__symmetric3_hpp__

#include <ostream>

namespace se3
{

  template<typename _Scalar, int _Options>
  class Symmetric3Tpl
  {
  public:
    typedef _Scalar Scalar;
    enum { Options = _Options };
    typedef Eigen::Matrix<Scalar,3,1,Options> Vector3;
    typedef Eigen::Matrix<Scalar,6,1,Options> Vector6;
    typedef Eigen::Matrix<Scalar,3,3,Options> Matrix3;
    typedef Eigen::Matrix<Scalar,2,2,Options> Matrix2;
    typedef Eigen::Matrix<Scalar,3,2,Options> Matrix32;

  public:
    Symmetric3Tpl(): data_() {}
    template<typename Sc,int N,int Opt>
    explicit Symmetric3Tpl(const Eigen::Matrix<Sc,N,N,Opt> & I)
    {
      assert( (I.rows()==3)&&(I.cols()==3) );
      assert( (I-I.transpose()).isMuchSmallerThan(I) );
      data_(0) = I(0,0);
      data_(1) = I(1,0); data_(2) = I(1,1);
      data_(3) = I(2,0); data_(4) = I(2,1); data_(5) = I(2,2);
    }
    explicit Symmetric3Tpl(const Eigen::MatrixBase<Matrix3> &I)
    {
      assert( (I-I.transpose()).isMuchSmallerThan(I) );
      data_(0) = I(0,0);
      data_(1) = I(1,0); data_(2) = I(1,1);
      data_(3) = I(2,0); data_(4) = I(2,1); data_(5) = I(2,2);
    }
    explicit Symmetric3Tpl(const Vector6 &I) : data_(I) {}
    Symmetric3Tpl(const double & a0,const double & a1,const double & a2,
		  const double & a3,const double & a4,const double & a5)
    { data_ << a0,a1,a2,a3,a4,a5; }

    static Symmetric3Tpl Zero()     { return Symmetric3Tpl(Vector6::Zero()  );  }
    static Symmetric3Tpl Random()   { return Symmetric3Tpl(Vector6::Random().eval());  }
    static Symmetric3Tpl Identity() { return Symmetric3Tpl( 1, 0, 1, 0, 0, 1);  }

    /* Requiered by Inertia::operator== */
    bool operator== (const Symmetric3Tpl & S2 ) { return data_ == S2.data_; }

    void setIdentity()
    {
      data_[0] = data_[2] = data_[5] = 1.;
      data_[1] = data_[3] = data_[4] = 0.;
    }

    void setZero() { data_.fill(0); }

    void fill(Scalar value) { data_.fill(value); }

    struct SkewSquare
    {
      const Vector3 & v;
      SkewSquare( const Vector3 & v ) : v(v) {}
      operator Symmetric3Tpl () const
      {
	const double & x = v[0], & y = v[1], & z = v[2];
	return Symmetric3Tpl( -y*y-z*z,
			      x*y    ,  -x*x-z*z,
			      x*z    ,   y*z    ,  -x*x-y*y );
      }
    }; // struct SkewSquare
    Symmetric3Tpl operator- (const SkewSquare & v) const
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      return Symmetric3Tpl( data_[0]+y*y+z*z,
			    data_[1]-x*y    ,  data_[2]+x*x+z*z,
			    data_[3]-x*z    ,  data_[4]-y*z    ,  data_[5]+x*x+y*y );
    }
    Symmetric3Tpl& operator-= (const SkewSquare & v)
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      data_[0]+=y*y+z*z;
      data_[1]-=x*y    ;  data_[2]+=x*x+z*z;
      data_[3]-=x*z    ;  data_[4]-=y*z    ;  data_[5]+=x*x+y*y;
      return *this;
    }

    struct AlphaSkewSquare
    {
      const double & m;  const Vector3 & v;
      AlphaSkewSquare( const double & m, const SkewSquare & v ) : m(m),v(v.v) {}
      operator Symmetric3Tpl () const
      {
	const double & x = v[0], & y = v[1], & z = v[2];
	return Symmetric3Tpl( -m*(y*y+z*z),
			       m* x*y     ,  -m*(x*x+z*z),
			       m* x*z     ,   m* y*z     ,  -m*(x*x+y*y) );
      }
    };
    friend AlphaSkewSquare operator* (const double & m, const SkewSquare & sk )
    { return AlphaSkewSquare(m,sk); }
    Symmetric3Tpl operator- (const AlphaSkewSquare & v) const
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      return Symmetric3Tpl( data_[0]+v.m*(y*y+z*z),
			    data_[1]-v.m* x*y     ,  data_[2]+v.m*(x*x+z*z),
			    data_[3]-v.m* x*z     ,  data_[4]-v.m* y*z     ,  data_[5]+v.m*(x*x+y*y) );
    }
    Symmetric3Tpl& operator-= (const AlphaSkewSquare & v)
    {
      const double & x = v.v[0], & y = v.v[1], & z = v.v[2];
      data_[0]+=v.m*(y*y+z*z);
      data_[1]-=v.m* x*y     ;  data_[2]+=v.m*(x*x+z*z);
      data_[3]-=v.m* x*z     ;  data_[4]-=v.m* y*z     ;  data_[5]+=v.m*(x*x+y*y);
      return *this;
    }

    const Vector6 & data () const {return data_;}
    Vector6 & data () {return data_;}

    // static Symmetric3Tpl SkewSq( const Vector3 & v )
    // {
    //   const double & x = v[0], & y = v[1], & z = v[2];
    //   return Symmetric3Tpl( -y*y-z*z,
    // 			    x*y    ,  -x*x-z*z,
    // 			    x*z    ,   y*z    ,  -x*x-y*y );
    // }

    /* Shoot a positive definite matrix. */
    static Symmetric3Tpl RandomPositive()
    {
      double
	a = double(std::rand())/RAND_MAX*2.0-1.0,
	b = double(std::rand())/RAND_MAX*2.0-1.0,
	c = double(std::rand())/RAND_MAX*2.0-1.0,
	d = double(std::rand())/RAND_MAX*2.0-1.0,
	e = double(std::rand())/RAND_MAX*2.0-1.0,
	f = double(std::rand())/RAND_MAX*2.0-1.0;
      return Symmetric3Tpl(a*a+b*b+d*d,
			   a*b+b*c+d*e, b*b+c*c+e*e,
			   a*d+b*e+d*f, b*d+c*e+e*f,  d*d+e*e+f*f );
    }

    Matrix3 matrix() const
    {
      Matrix3 res;
      res(0,0) = data_(0); res(0,1) = data_(1); res(0,2) = data_(3);
      res(1,0) = data_(1); res(1,1) = data_(2); res(1,2) = data_(4);
      res(2,0) = data_(3); res(2,1) = data_(4); res(2,2) = data_(5);
      return res;
    }
    operator Matrix3 () const { return matrix(); }

    Symmetric3Tpl operator+(const Symmetric3Tpl & s2) const
    {
      return Symmetric3Tpl((data_+s2.data_).eval());
    }

    Symmetric3Tpl & operator+=(const Symmetric3Tpl & s2)
    {
      data_ += s2.data_; return *this;
    }

    Vector3 operator*(const Vector3 &v) const
    {
      return Vector3(
		     data_(0) * v(0) + data_(1) * v(1) + data_(3) * v(2),
		     data_(1) * v(0) + data_(2) * v(1) + data_(4) * v(2),
		     data_(3) * v(0) + data_(4) * v(1) + data_(5) * v(2)
		     );
    }

    // Matrix3 operator*(const Matrix3 &a) const
    // {
    //   Matrix3 r;
    //   for(unsigned int i=0; i<3; ++i)
    //     {
    //       r(0,i) = data_(0) * a(0,i) + data_(1) * a(1,i) + data_(3) * a(2,i);
    //       r(1,i) = data_(1) * a(0,i) + data_(2) * a(1,i) + data_(4) * a(2,i);
    //       r(2,i) = data_(3) * a(0,i) + data_(4) * a(1,i) + data_(5) * a(2,i);
    //     }
    //   return r;
    // }

    const Scalar& operator()(const int &i,const int &j) const
    {
      return ((i!=2)&&(j!=2)) ? data_[i+j] : data_[i+j+1];
    }

    Symmetric3Tpl operator-(const Matrix3 &S) const
    {
      assert( (S-S.transpose()).isMuchSmallerThan(S) );
      return Symmetric3Tpl( data_(0)-S(0,0),
			    data_(1)-S(1,0), data_(2)-S(1,1),
			    data_(3)-S(2,0), data_(4)-S(2,1), data_(5)-S(2,2) );
    }

    Symmetric3Tpl operator+(const Matrix3 &S) const
    {
      assert( (S-S.transpose()).isMuchSmallerThan(S) );
      return Symmetric3Tpl( data_(0)+S(0,0),
			    data_(1)+S(1,0), data_(2)+S(1,1),
			    data_(3)+S(2,0), data_(4)+S(2,1), data_(5)+S(2,2) );
    }

    /* --- Symmetric R*S*R' and R'*S*R products --- */
  public: //private:

    /** \brief Computes L for a symmetric matrix A.
     */
    Matrix32  decomposeltI() const
    {
      Matrix32 L;
      L <<
	data_(0) - data_(5),    data_(1),
	data_(1),              data_(2) - data_(5),
	2*data_(3),            data_(4) + data_(4);
      return L;
    }

    /* R*S*R' */
    template<typename D>
    Symmetric3Tpl rotate(const Eigen::MatrixBase<D> & R) const
    {
      assert( (R.cols()==3) && (R.rows()==3) );
      assert( (R.transpose()*R).isApprox(Matrix3::Identity()) );

      Symmetric3Tpl Sres;

      // 4 a
      const Matrix32 L( decomposeltI() );

      // Y = R' L   ===> (12 m + 8 a)
      const Matrix2 Y( R.template block<2,3>(1,0) * L );

      // Sres= Y R  ===> (16 m + 8a)
      Sres.data_(1) = Y(0,0)*R(0,0) + Y(0,1)*R(0,1);
      Sres.data_(2) = Y(0,0)*R(1,0) + Y(0,1)*R(1,1);
      Sres.data_(3) = Y(1,0)*R(0,0) + Y(1,1)*R(0,1);
      Sres.data_(4) = Y(1,0)*R(1,0) + Y(1,1)*R(1,1);
      Sres.data_(5) = Y(1,0)*R(2,0) + Y(1,1)*R(2,1);

      // r=R' v ( 6m + 3a)
      const Vector3 r( -R(0,0)*data_(4) + R(0,1)*data_(3),
		       -R(1,0)*data_(4) + R(1,1)*data_(3),
		       -R(2,0)*data_(4) + R(2,1)*data_(3) );

      // Sres_11 (3a)
      Sres.data_(0) = L(0,0) + L(1,1) - Sres.data_(2) - Sres.data_(5);

      // Sres + D + (Ev)x ( 9a)
      Sres.data_(0) += data_(5);
      Sres.data_(1) += r(2);    Sres.data_(2)+= data_(5);
      Sres.data_(3) +=-r(1);    Sres.data_(4)+=    r(0); Sres.data_(5) += data_(5);

      return Sres;
    }

  private:

    Vector6 data_;
  };

  typedef Symmetric3Tpl<double,0> Symmetric3;

} // namespace se3

#endif // ifndef __se3__symmetric3_hpp__

<|endoftext|>


<commit_before>#include <stan/version.hpp>
#include <stan/gm/compiler.hpp>

#include <exception>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>

#include <stan/io/cmd_line.hpp>

/**
 * Prints the Stan version to std::cout.
 *
 */
void print_version() {
  std::cout << "stanc version "
            << stan::MAJOR_VERSION
            << "."
            << stan::MINOR_VERSION
            << "."
            << stan::PATCH_VERSION
            << std::endl;
}

/**
 * Prints the Stan compiler (stanc) help
 * to std::cout.
 *
 */
void print_stanc_help() {
  using stan::io::print_help_option;

  std::cout << std::endl;
  print_version();
  std::cout << std::endl;

  std::cout << "USAGE:  " << "stanc [options] <model_file>" << std::endl;
  std::cout << std::endl;

  std::cout << "OPTIONS:" << std::endl;
  std::cout << std::endl;

  print_help_option("help","","Display this information");

  print_help_option("version","","Display stanc version number");

  print_help_option("name","string",
                    "Model name",
                    "default = \"$model_filename_model\"");

  print_help_option("o","file",
                    "Output file for generated C++ code",
                    "default = \"$name.cpp\"");

}

/**
 * The Stan compiler (stanc).
 *
 * @param argc Number of arguments
 * @param argv Arguments
 *
 * @return 0 for success, -1 for exception, -2 for parser failure
 */
int main(int argc, const char* argv[]) {

  static const int SUCCESS_RC = 0;
  static const int EXCEPTION_RC = -1;
  static const int PARSE_FAIL_RC = -2;

  stan::io::cmd_line cmd(argc,argv);

  if (cmd.has_flag("help")) {
    print_stanc_help();
    return SUCCESS_RC;
  }

  if (cmd.has_flag("version")) {
    print_version();
    return SUCCESS_RC;
  }

  stan::gm::program prog;
  try {
    if (cmd.bare_size() != 1) {
      std::string msg("require file name to compile as input. "
                      "execute \"stanc --help\" for more information");
      throw std::invalid_argument(msg);
    }
    std::string in_file_name;
    cmd.bare(0,in_file_name);
    std::fstream in(in_file_name.c_str());

    std::string model_name;
    if (cmd.has_key("name")) {
      cmd.val("name",model_name);
    } else {
      size_t slashInd = in_file_name.rfind('/');
      size_t ptInd = in_file_name.rfind('.');
      if (ptInd == std::string::npos)
        ptInd = in_file_name.length();
      if (slashInd == std::string::npos) {
        slashInd = in_file_name.rfind('\\');
      }
      if (slashInd == std::string::npos) {
        slashInd = 0;
      } else {
        slashInd++;
      }
      model_name = in_file_name.substr(slashInd,ptInd - slashInd) + "_model";
      for (std::string::iterator strIt = model_name.begin();
           strIt != model_name.end(); strIt++) {
        if (!isalnum(*strIt) && *strIt != '_') {
          *strIt = '_';
        }
      }
    }
    if (!isalpha(model_name[0]) && model_name[0] != '_') {
      std::string msg("model_name must not start with a number or symbol other than _");
      throw std::invalid_argument(msg);
    }
    for (std::string::iterator strIt = model_name.begin();
         strIt != model_name.end(); strIt++) {
      if (!isalnum(*strIt) && *strIt != '_') {
        std::string msg("model_name must contain only letters, numbers and _");
        throw std::invalid_argument(msg);
      }
    }

    std::string out_file_name;
    if (cmd.has_key("o")) {
      cmd.val("o",out_file_name);
    } else {
      out_file_name = model_name;
      out_file_name += ".cpp";
    }
    std::fstream out(out_file_name.c_str(),
                     std::fstream::out);

    std::cout << "Model name=" << model_name << std::endl;
    std::cout << "Input file=" << in_file_name << std::endl;
    std::cout << "Output file=" << out_file_name << std::endl;

    bool include_main = !cmd.has_flag("no_main");

    bool valid_model
      = stan::gm::compile(in,out,model_name,include_main);

    out.close();

    if (!valid_model) {
      std::cout << "PARSING FAILED." << std::endl;
      return PARSE_FAIL_RC;
    }

  } catch (const std::exception& e) {
    std::cout << std::endl
              << "ERROR PARSING"
              << std::endl
              << e.what()
              << std::endl;
    return EXCEPTION_RC;
  }

  return SUCCESS_RC;
}

<commit_msg>fixed stanc to remove output file if parsing fails, closing issue 57<commit_after>#include <stan/version.hpp>
#include <stan/gm/compiler.hpp>

#include <cstdio>
#include <exception>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <string>

#include <stan/io/cmd_line.hpp>

/**
 * Prints the Stan version to std::cout.
 *
 */
void print_version() {
  std::cout << "stanc version "
            << stan::MAJOR_VERSION
            << "."
            << stan::MINOR_VERSION
            << "."
            << stan::PATCH_VERSION
            << std::endl;
}

/**
 * Prints the Stan compiler (stanc) help
 * to std::cout.
 *
 */
void print_stanc_help() {
  using stan::io::print_help_option;

  std::cout << std::endl;
  print_version();
  std::cout << std::endl;

  std::cout << "USAGE:  " << "stanc [options] <model_file>" << std::endl;
  std::cout << std::endl;

  std::cout << "OPTIONS:" << std::endl;
  std::cout << std::endl;

  print_help_option("help","","Display this information");

  print_help_option("version","","Display stanc version number");

  print_help_option("name","string",
                    "Model name",
                    "default = \"$model_filename_model\"");

  print_help_option("o","file",
                    "Output file for generated C++ code",
                    "default = \"$name.cpp\"");

}

void delete_file(const std::string& file_name) {
  int deleted = std::remove(file_name.c_str());
  std::cout << (deleted == 0
                ? "OUTPUT FILE REMOVED"
                : "COULD NOT REMOVE OUTPUT FILE")
            << ", file=" << file_name.c_str()
            << std::endl;
}

/**
 * The Stan compiler (stanc).
 *
 * @param argc Number of arguments
 * @param argv Arguments
 *
 * @return 0 for success, -1 for exception, -2 for parser failure
 */
int main(int argc, const char* argv[]) {

  static const int SUCCESS_RC = 0;
  static const int EXCEPTION_RC = -1;
  static const int PARSE_FAIL_RC = -2;

  stan::io::cmd_line cmd(argc,argv);

  if (cmd.has_flag("help")) {
    print_stanc_help();
    return SUCCESS_RC;
  }

  if (cmd.has_flag("version")) {
    print_version();
    return SUCCESS_RC;
  }

  if (cmd.bare_size() != 1) {
    std::string msg("require file name to compile as input. "
                    "execute \"stanc --help\" for more information");
    throw std::invalid_argument(msg);
  }
  std::string in_file_name;
  cmd.bare(0,in_file_name);
  std::fstream in(in_file_name.c_str());

  std::string model_name;
  if (cmd.has_key("name")) {
    cmd.val("name",model_name);
  } else {
    size_t slashInd = in_file_name.rfind('/');
    size_t ptInd = in_file_name.rfind('.');
    if (ptInd == std::string::npos)
      ptInd = in_file_name.length();
    if (slashInd == std::string::npos) {
      slashInd = in_file_name.rfind('\\');
    }
    if (slashInd == std::string::npos) {
      slashInd = 0;
    } else {
      slashInd++;
    }
    model_name = in_file_name.substr(slashInd,ptInd - slashInd) + "_model";
    for (std::string::iterator strIt = model_name.begin();
         strIt != model_name.end(); strIt++) {
      if (!isalnum(*strIt) && *strIt != '_') {
        *strIt = '_';
      }
    }
  }

  std::string out_file_name;
  if (cmd.has_key("o")) {
    cmd.val("o",out_file_name);
  } else {
    out_file_name = model_name;
    out_file_name += ".cpp";
  }

  if (!isalpha(model_name[0]) && model_name[0] != '_') {
    std::string msg("model_name must not start with a number or symbol other than _");
    throw std::invalid_argument(msg);
  }
  for (std::string::iterator strIt = model_name.begin();
       strIt != model_name.end(); strIt++) {
    if (!isalnum(*strIt) && *strIt != '_') {
      std::string msg("model_name must contain only letters, numbers and _");
      throw std::invalid_argument(msg);
    }
  }

  stan::gm::program prog;
  try {
    std::fstream out(out_file_name.c_str(),
                     std::fstream::out);
    std::cout << "Model name=" << model_name << std::endl;
    std::cout << "Input file=" << in_file_name << std::endl;
    std::cout << "Output file=" << out_file_name << std::endl;
    bool include_main = !cmd.has_flag("no_main");
    bool valid_model
      = stan::gm::compile(in,out,model_name,include_main);
    out.close();
    if (!valid_model) {
      std::cout << "PARSING FAILED." << std::endl;
      delete_file(out_file_name);
      return PARSE_FAIL_RC;
    }
  } catch (const std::exception& e) {
    std::cout << std::endl
              << "ERROR PARSING"
              << std::endl
              << e.what()
              << std::endl;
    delete_file(out_file_name);
    return EXCEPTION_RC;
  }

  return SUCCESS_RC;
}

<|endoftext|>


<commit_before>/*************************************************************************/
/*  open_simplex_noise.cpp                                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "open_simplex_noise.h"

#include "core/core_string_names.h"

OpenSimplexNoise::OpenSimplexNoise() {
	seed = 0;
	persistence = 0.5;
	octaves = 3;
	period = 64;
	lacunarity = 2.0;

	_init_seeds();
}

OpenSimplexNoise::~OpenSimplexNoise() {
}

void OpenSimplexNoise::_init_seeds() {
	for (int i = 0; i < MAX_OCTAVES; ++i) {
		open_simplex_noise(seed + i * 2, &(contexts[i]));
	}
}

void OpenSimplexNoise::set_seed(int p_seed) {
	if (seed == p_seed) {
		return;
	}

	seed = p_seed;

	_init_seeds();

	emit_changed();
}

int OpenSimplexNoise::get_seed() const {
	return seed;
}

void OpenSimplexNoise::set_octaves(int p_octaves) {
	if (p_octaves == octaves) {
		return;
	}

	ERR_FAIL_COND_MSG(p_octaves > MAX_OCTAVES, vformat("The number of OpenSimplexNoise octaves is limited to %d; ignoring the new value.", MAX_OCTAVES));

	octaves = CLAMP(p_octaves, 1, MAX_OCTAVES);
	emit_changed();
}

void OpenSimplexNoise::set_period(float p_period) {
	if (p_period == period) {
		return;
	}
	period = p_period;
	emit_changed();
}

void OpenSimplexNoise::set_persistence(float p_persistence) {
	if (p_persistence == persistence) {
		return;
	}
	persistence = p_persistence;
	emit_changed();
}

void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
	if (p_lacunarity == lacunarity) {
		return;
	}
	lacunarity = p_lacunarity;
	emit_changed();
}

Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
	PoolVector<uint8_t> data;
	data.resize(p_width * p_height);

	PoolVector<uint8_t>::Write wd8 = data.write();

	for (int i = 0; i < p_height; i++) {
		for (int j = 0; j < p_width; j++) {
			float v = get_noise_2d(i, j);
			v = v * 0.5 + 0.5; // Normalize [0..1]
			wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
		}
	}

	Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data));
	return image;
}

Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const {
	PoolVector<uint8_t> data;
	data.resize(p_size * p_size);

	PoolVector<uint8_t>::Write wd8 = data.write();

	for (int i = 0; i < p_size; i++) {
		for (int j = 0; j < p_size; j++) {
			float ii = (float)i / (float)p_size;
			float jj = (float)j / (float)p_size;

			ii *= 2.0 * Math_PI;
			jj *= 2.0 * Math_PI;

			float radius = p_size / (2.0 * Math_PI);

			float x = radius * Math::sin(jj);
			float y = radius * Math::cos(jj);
			float z = radius * Math::sin(ii);
			float w = radius * Math::cos(ii);
			float v = get_noise_4d(x, y, z, w);

			v = v * 0.5 + 0.5; // Normalize [0..1]
			wd8[(i * p_size + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
		}
	}

	Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_L8, data));
	return image;
}

void OpenSimplexNoise::_bind_methods() {
	ClassDB::bind_method(D_METHOD("get_seed"), &OpenSimplexNoise::get_seed);
	ClassDB::bind_method(D_METHOD("set_seed", "seed"), &OpenSimplexNoise::set_seed);

	ClassDB::bind_method(D_METHOD("set_octaves", "octave_count"), &OpenSimplexNoise::set_octaves);
	ClassDB::bind_method(D_METHOD("get_octaves"), &OpenSimplexNoise::get_octaves);

	ClassDB::bind_method(D_METHOD("set_period", "period"), &OpenSimplexNoise::set_period);
	ClassDB::bind_method(D_METHOD("get_period"), &OpenSimplexNoise::get_period);

	ClassDB::bind_method(D_METHOD("set_persistence", "persistence"), &OpenSimplexNoise::set_persistence);
	ClassDB::bind_method(D_METHOD("get_persistence"), &OpenSimplexNoise::get_persistence);

	ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &OpenSimplexNoise::set_lacunarity);
	ClassDB::bind_method(D_METHOD("get_lacunarity"), &OpenSimplexNoise::get_lacunarity);

	ClassDB::bind_method(D_METHOD("get_image", "width", "height"), &OpenSimplexNoise::get_image);
	ClassDB::bind_method(D_METHOD("get_seamless_image", "size"), &OpenSimplexNoise::get_seamless_image);

	ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &OpenSimplexNoise::get_noise_1d);
	ClassDB::bind_method(D_METHOD("get_noise_2d", "x", "y"), &OpenSimplexNoise::get_noise_2d);
	ClassDB::bind_method(D_METHOD("get_noise_3d", "x", "y", "z"), &OpenSimplexNoise::get_noise_3d);
	ClassDB::bind_method(D_METHOD("get_noise_4d", "x", "y", "z", "w"), &OpenSimplexNoise::get_noise_4d);

	ClassDB::bind_method(D_METHOD("get_noise_2dv", "pos"), &OpenSimplexNoise::get_noise_2dv);
	ClassDB::bind_method(D_METHOD("get_noise_3dv", "pos"), &OpenSimplexNoise::get_noise_3dv);

	ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", MAX_OCTAVES)), "set_octaves", "get_octaves");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
}

float OpenSimplexNoise::get_noise_1d(float x) const {
	return get_noise_2d(x, 1.0);
}

float OpenSimplexNoise::get_noise_2d(float x, float y) const {
	x /= period;
	y /= period;

	float amp = 1.0;
	float max = 1.0;
	float sum = _get_octave_noise_2d(0, x, y);

	int i = 0;
	while (++i < octaves) {
		x *= lacunarity;
		y *= lacunarity;
		amp *= persistence;
		max += amp;
		sum += _get_octave_noise_2d(i, x, y) * amp;
	}

	return sum / max;
}

float OpenSimplexNoise::get_noise_3d(float x, float y, float z) const {
	x /= period;
	y /= period;
	z /= period;

	float amp = 1.0;
	float max = 1.0;
	float sum = _get_octave_noise_3d(0, x, y, z);

	int i = 0;
	while (++i < octaves) {
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
		amp *= persistence;
		max += amp;
		sum += _get_octave_noise_3d(i, x, y, z) * amp;
	}

	return sum / max;
}

float OpenSimplexNoise::get_noise_4d(float x, float y, float z, float w) const {
	x /= period;
	y /= period;
	z /= period;
	w /= period;

	float amp = 1.0;
	float max = 1.0;
	float sum = _get_octave_noise_4d(0, x, y, z, w);

	int i = 0;
	while (++i < octaves) {
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
		w *= lacunarity;
		amp *= persistence;
		max += amp;
		sum += _get_octave_noise_4d(i, x, y, z, w) * amp;
	}

	return sum / max;
}
<commit_msg>Fix OpenSimplexNoise get_image() swap axes<commit_after>/*************************************************************************/
/*  open_simplex_noise.cpp                                               */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "open_simplex_noise.h"

#include "core/core_string_names.h"

OpenSimplexNoise::OpenSimplexNoise() {
	seed = 0;
	persistence = 0.5;
	octaves = 3;
	period = 64;
	lacunarity = 2.0;

	_init_seeds();
}

OpenSimplexNoise::~OpenSimplexNoise() {
}

void OpenSimplexNoise::_init_seeds() {
	for (int i = 0; i < MAX_OCTAVES; ++i) {
		open_simplex_noise(seed + i * 2, &(contexts[i]));
	}
}

void OpenSimplexNoise::set_seed(int p_seed) {
	if (seed == p_seed) {
		return;
	}

	seed = p_seed;

	_init_seeds();

	emit_changed();
}

int OpenSimplexNoise::get_seed() const {
	return seed;
}

void OpenSimplexNoise::set_octaves(int p_octaves) {
	if (p_octaves == octaves) {
		return;
	}

	ERR_FAIL_COND_MSG(p_octaves > MAX_OCTAVES, vformat("The number of OpenSimplexNoise octaves is limited to %d; ignoring the new value.", MAX_OCTAVES));

	octaves = CLAMP(p_octaves, 1, MAX_OCTAVES);
	emit_changed();
}

void OpenSimplexNoise::set_period(float p_period) {
	if (p_period == period) {
		return;
	}
	period = p_period;
	emit_changed();
}

void OpenSimplexNoise::set_persistence(float p_persistence) {
	if (p_persistence == persistence) {
		return;
	}
	persistence = p_persistence;
	emit_changed();
}

void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
	if (p_lacunarity == lacunarity) {
		return;
	}
	lacunarity = p_lacunarity;
	emit_changed();
}

Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) const {
	PoolVector<uint8_t> data;
	data.resize(p_width * p_height);

	PoolVector<uint8_t>::Write wd8 = data.write();

	for (int i = 0; i < p_height; i++) {
		for (int j = 0; j < p_width; j++) {
			float v = get_noise_2d(j, i);
			v = v * 0.5 + 0.5; // Normalize [0..1]
			wd8[(i * p_width + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
		}
	}

	Ref<Image> image = memnew(Image(p_width, p_height, false, Image::FORMAT_L8, data));
	return image;
}

Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) const {
	PoolVector<uint8_t> data;
	data.resize(p_size * p_size);

	PoolVector<uint8_t>::Write wd8 = data.write();

	for (int i = 0; i < p_size; i++) {
		for (int j = 0; j < p_size; j++) {
			float ii = (float)i / (float)p_size;
			float jj = (float)j / (float)p_size;

			ii *= 2.0 * Math_PI;
			jj *= 2.0 * Math_PI;

			float radius = p_size / (2.0 * Math_PI);

			float x = radius * Math::sin(jj);
			float y = radius * Math::cos(jj);
			float z = radius * Math::sin(ii);
			float w = radius * Math::cos(ii);
			float v = get_noise_4d(x, y, z, w);

			v = v * 0.5 + 0.5; // Normalize [0..1]
			wd8[(i * p_size + j)] = uint8_t(CLAMP(v * 255.0, 0, 255));
		}
	}

	Ref<Image> image = memnew(Image(p_size, p_size, false, Image::FORMAT_L8, data));
	return image;
}

void OpenSimplexNoise::_bind_methods() {
	ClassDB::bind_method(D_METHOD("get_seed"), &OpenSimplexNoise::get_seed);
	ClassDB::bind_method(D_METHOD("set_seed", "seed"), &OpenSimplexNoise::set_seed);

	ClassDB::bind_method(D_METHOD("set_octaves", "octave_count"), &OpenSimplexNoise::set_octaves);
	ClassDB::bind_method(D_METHOD("get_octaves"), &OpenSimplexNoise::get_octaves);

	ClassDB::bind_method(D_METHOD("set_period", "period"), &OpenSimplexNoise::set_period);
	ClassDB::bind_method(D_METHOD("get_period"), &OpenSimplexNoise::get_period);

	ClassDB::bind_method(D_METHOD("set_persistence", "persistence"), &OpenSimplexNoise::set_persistence);
	ClassDB::bind_method(D_METHOD("get_persistence"), &OpenSimplexNoise::get_persistence);

	ClassDB::bind_method(D_METHOD("set_lacunarity", "lacunarity"), &OpenSimplexNoise::set_lacunarity);
	ClassDB::bind_method(D_METHOD("get_lacunarity"), &OpenSimplexNoise::get_lacunarity);

	ClassDB::bind_method(D_METHOD("get_image", "width", "height"), &OpenSimplexNoise::get_image);
	ClassDB::bind_method(D_METHOD("get_seamless_image", "size"), &OpenSimplexNoise::get_seamless_image);

	ClassDB::bind_method(D_METHOD("get_noise_1d", "x"), &OpenSimplexNoise::get_noise_1d);
	ClassDB::bind_method(D_METHOD("get_noise_2d", "x", "y"), &OpenSimplexNoise::get_noise_2d);
	ClassDB::bind_method(D_METHOD("get_noise_3d", "x", "y", "z"), &OpenSimplexNoise::get_noise_3d);
	ClassDB::bind_method(D_METHOD("get_noise_4d", "x", "y", "z", "w"), &OpenSimplexNoise::get_noise_4d);

	ClassDB::bind_method(D_METHOD("get_noise_2dv", "pos"), &OpenSimplexNoise::get_noise_2dv);
	ClassDB::bind_method(D_METHOD("get_noise_3dv", "pos"), &OpenSimplexNoise::get_noise_3dv);

	ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "octaves", PROPERTY_HINT_RANGE, vformat("1,%d,1", MAX_OCTAVES)), "set_octaves", "get_octaves");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "period", PROPERTY_HINT_RANGE, "0.1,256.0,0.1"), "set_period", "get_period");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "persistence", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_persistence", "get_persistence");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "lacunarity", PROPERTY_HINT_RANGE, "0.1,4.0,0.01"), "set_lacunarity", "get_lacunarity");
}

float OpenSimplexNoise::get_noise_1d(float x) const {
	return get_noise_2d(x, 1.0);
}

float OpenSimplexNoise::get_noise_2d(float x, float y) const {
	x /= period;
	y /= period;

	float amp = 1.0;
	float max = 1.0;
	float sum = _get_octave_noise_2d(0, x, y);

	int i = 0;
	while (++i < octaves) {
		x *= lacunarity;
		y *= lacunarity;
		amp *= persistence;
		max += amp;
		sum += _get_octave_noise_2d(i, x, y) * amp;
	}

	return sum / max;
}

float OpenSimplexNoise::get_noise_3d(float x, float y, float z) const {
	x /= period;
	y /= period;
	z /= period;

	float amp = 1.0;
	float max = 1.0;
	float sum = _get_octave_noise_3d(0, x, y, z);

	int i = 0;
	while (++i < octaves) {
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
		amp *= persistence;
		max += amp;
		sum += _get_octave_noise_3d(i, x, y, z) * amp;
	}

	return sum / max;
}

float OpenSimplexNoise::get_noise_4d(float x, float y, float z, float w) const {
	x /= period;
	y /= period;
	z /= period;
	w /= period;

	float amp = 1.0;
	float max = 1.0;
	float sum = _get_octave_noise_4d(0, x, y, z, w);

	int i = 0;
	while (++i < octaves) {
		x *= lacunarity;
		y *= lacunarity;
		z *= lacunarity;
		w *= lacunarity;
		amp *= persistence;
		max += amp;
		sum += _get_octave_noise_4d(i, x, y, z, w) * amp;
	}

	return sum / max;
}
<|endoftext|>


<commit_before>#ifndef STAN_MATH_REV_FUNCTOR_INTEGRATE_ODE_CVODES_HPP
#define STAN_MATH_REV_FUNCTOR_INTEGRATE_ODE_CVODES_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/functor/coupled_ode_system.hpp>
#include <stan/math/rev/functor/cvodes_utils.hpp>
#include <stan/math/rev/functor/cvodes_ode_data.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/value_of.hpp>
#include <stan/math/prim/functor/coupled_ode_observer.hpp>
#include <stan/math/prim/functor/coupled_ode_system.hpp>
#include <cvodes/cvodes.h>
#include <sunlinsol/sunlinsol_dense.h>
#include <algorithm>
#include <ostream>
#include <vector>

namespace stan {
namespace math {

/**
 * Integrator interface for CVODES' ODE solvers (Adams & BDF
 * methods).
 *
 * @tparam Lmm ID of ODE solver (1: ADAMS, 2: BDF)
 */
template <int Lmm>
class cvodes_integrator {
 public:
  cvodes_integrator() {}

  /**
   * Return the solutions for the specified system of ordinary
   * differential equations given the specified initial state,
   * initial times, times of desired solution, and parameters and
   * data, writing error and warning messages to the specified
   * stream.
   *
   * This function is templated to allow the initials to be
   * either data or autodiff variables and the parameters to be data
   * or autodiff variables.  The autodiff-based implementation for
   * reverse-mode are defined in namespace stan::math
   * and may be invoked via argument-dependent lookup by including
   * their headers.
   *
   * The solver used is based on the backward differentiation
   * formula which is an implicit numerical integration scheme
   * appropriate for stiff ODE systems.
   *
   * @tparam F type of ODE system function.
   * @tparam T_initial type of scalars for initial values.
   * @tparam T_param type of scalars for parameters.
   * @tparam T_t0 type of scalar of initial time point.
   * @tparam T_ts type of time-points where ODE solution is returned.
   *
   * @param[in] f functor for the base ordinary differential equation.
   * @param[in] y0 initial state.
   * @param[in] t0 initial time.
   * @param[in] ts times of the desired solutions, in strictly
   * increasing order, all greater than the initial time.
   * @param[in] theta parameter vector for the ODE.
   * @param[in] x continuous data vector for the ODE.
   * @param[in] x_int integer data vector for the ODE.
   * @param[in, out] msgs the print stream for warning messages.
   * @param[in] relative_tolerance relative tolerance passed to CVODE.
   * @param[in] absolute_tolerance absolute tolerance passed to CVODE.
   * @param[in] max_num_steps maximal number of admissable steps
   * between time-points
   * @return a vector of states, each state being a vector of the
   * same size as the state variable, corresponding to a time in ts.
   */
  template <typename F, typename T_initial, typename T_param, typename T_t0,
            typename T_ts>
  std::vector<std::vector<return_type_t<T_initial, T_param, T_t0, T_ts>>>
  integrate(const char* fun, const F& f, const std::vector<T_initial>& y0, const T_t0& t0,
            const std::vector<T_ts>& ts, const std::vector<T_param>& theta,
            const std::vector<double>& x, const std::vector<int>& x_int,
            std::ostream* msgs, double relative_tolerance,
            double absolute_tolerance,
            long int max_num_steps) {  // NOLINT(runtime/int)
    using initial_var = stan::is_var<T_initial>;
    using param_var = stan::is_var<T_param>;

    const double t0_dbl = value_of(t0);
    const std::vector<double> ts_dbl = value_of(ts);

    check_finite(fun, "initial state", y0);
    check_finite(fun, "initial time", t0_dbl);
    check_finite(fun, "times", ts_dbl);
    check_finite(fun, "parameter vector", theta);
    check_finite(fun, "continuous data", x);
    check_nonzero_size(fun, "times", ts);
    check_nonzero_size(fun, "initial state", y0);
    check_ordered(fun, "times", ts_dbl);
    check_less(fun, "initial time", t0_dbl, ts_dbl[0]);
    if (relative_tolerance <= 0) {
      invalid_argument(fun, "relative_tolerance,", relative_tolerance, "",
                       ", must be greater than 0");
    }
    if (absolute_tolerance <= 0) {
      invalid_argument(fun, "absolute_tolerance,", absolute_tolerance, "",
                       ", must be greater than 0");
    }
    if (max_num_steps <= 0) {
      invalid_argument(fun, "max_num_steps,", max_num_steps, "",
                       ", must be greater than 0");
    }

    const size_t N = y0.size();
    const size_t M = theta.size();
    const size_t S = (initial_var::value ? N : 0) + (param_var::value ? M : 0);

    using ode_data = cvodes_ode_data<F, T_initial, T_param>;
    ode_data cvodes_data(f, y0, theta, x, x_int, msgs);

    void* cvodes_mem = CVodeCreate(Lmm);
    if (cvodes_mem == nullptr) {
      throw std::runtime_error("CVodeCreate failed to allocate memory");
    }

    const size_t coupled_size = cvodes_data.coupled_ode_.size();

    std::vector<std::vector<return_type_t<T_initial, T_param, T_t0, T_ts>>> y;
    coupled_ode_observer<F, T_initial, T_param, T_t0, T_ts> observer(
        f, y0, theta, t0, ts, x, x_int, msgs, y);

    try {
      check_flag_sundials(CVodeInit(cvodes_mem, &ode_data::cv_rhs, t0_dbl,
                                    cvodes_data.nv_state_),
                          "CVodeInit");

      // Assign pointer to this as user data
      check_flag_sundials(
          CVodeSetUserData(cvodes_mem, reinterpret_cast<void*>(&cvodes_data)),
          "CVodeSetUserData");

      cvodes_set_options(cvodes_mem, relative_tolerance, absolute_tolerance,
                         max_num_steps);

      // for the stiff solvers we need to reserve additional memory
      // and provide a Jacobian function call. new API since 3.0.0:
      // create matrix object and linear solver object; resource
      // (de-)allocation is handled in the cvodes_ode_data
      check_flag_sundials(
          CVodeSetLinearSolver(cvodes_mem, cvodes_data.LS_, cvodes_data.A_),
          "CVodeSetLinearSolver");
      check_flag_sundials(
          CVodeSetJacFn(cvodes_mem, &ode_data::cv_jacobian_states),
          "CVodeSetJacFn");

      // initialize forward sensitivity system of CVODES as needed
      if (S > 0) {
        check_flag_sundials(
            CVodeSensInit(cvodes_mem, static_cast<int>(S), CV_STAGGERED,
                          &ode_data::cv_rhs_sens, cvodes_data.nv_state_sens_),
            "CVodeSensInit");

        check_flag_sundials(CVodeSensEEtolerances(cvodes_mem),
                            "CVodeSensEEtolerances");
      }

      double t_init = t0_dbl;
      for (size_t n = 0; n < ts.size(); ++n) {
        double t_final = ts_dbl[n];
        if (t_final != t_init) {
          int ret = CVode(cvodes_mem, t_final, cvodes_data.nv_state_, &t_init,
                          CV_NORMAL);

          if (ret == CV_TOO_MUCH_WORK) {
            throw_domain_error(fun, "", t_final,
                               "Failed to integrate to next output time (",
                               ") in less than max_num_steps steps");
          }
        }
        if (S > 0) {
          check_flag_sundials(
              CVodeGetSens(cvodes_mem, &t_init, cvodes_data.nv_state_sens_),
              "CVodeGetSens");
        }
        observer(cvodes_data.coupled_state_, t_final);
        t_init = t_final;
      }
    } catch (const std::exception& e) {
      CVodeFree(&cvodes_mem);
      throw;
    }

    CVodeFree(&cvodes_mem);

    return y;
  }
};  // cvodes integrator

}  // namespace math
}  // namespace stan
#endif
<commit_msg>Added docs for function name argument in cvodes_integrator (Issue #1887)<commit_after>#ifndef STAN_MATH_REV_FUNCTOR_INTEGRATE_ODE_CVODES_HPP
#define STAN_MATH_REV_FUNCTOR_INTEGRATE_ODE_CVODES_HPP

#include <stan/math/rev/meta.hpp>
#include <stan/math/rev/functor/coupled_ode_system.hpp>
#include <stan/math/rev/functor/cvodes_utils.hpp>
#include <stan/math/rev/functor/cvodes_ode_data.hpp>
#include <stan/math/prim/err.hpp>
#include <stan/math/prim/fun/value_of.hpp>
#include <stan/math/prim/functor/coupled_ode_observer.hpp>
#include <stan/math/prim/functor/coupled_ode_system.hpp>
#include <cvodes/cvodes.h>
#include <sunlinsol/sunlinsol_dense.h>
#include <algorithm>
#include <ostream>
#include <vector>

namespace stan {
namespace math {

/**
 * Integrator interface for CVODES' ODE solvers (Adams & BDF
 * methods).
 *
 * @tparam Lmm ID of ODE solver (1: ADAMS, 2: BDF)
 */
template <int Lmm>
class cvodes_integrator {
 public:
  cvodes_integrator() {}

  /**
   * Return the solutions for the specified system of ordinary
   * differential equations given the specified initial state,
   * initial times, times of desired solution, and parameters and
   * data, writing error and warning messages to the specified
   * stream.
   *
   * This function is templated to allow the initials to be
   * either data or autodiff variables and the parameters to be data
   * or autodiff variables.  The autodiff-based implementation for
   * reverse-mode are defined in namespace stan::math
   * and may be invoked via argument-dependent lookup by including
   * their headers.
   *
   * The solver used is based on the backward differentiation
   * formula which is an implicit numerical integration scheme
   * appropriate for stiff ODE systems.
   *
   * @tparam F type of ODE system function.
   * @tparam T_initial type of scalars for initial values.
   * @tparam T_param type of scalars for parameters.
   * @tparam T_t0 type of scalar of initial time point.
   * @tparam T_ts type of time-points where ODE solution is returned.
   *
   * @param[in] function_name name of function for error messages
   * @param[in] f functor for the base ordinary differential equation.
   * @param[in] y0 initial state.
   * @param[in] t0 initial time.
   * @param[in] ts times of the desired solutions, in strictly
   * increasing order, all greater than the initial time.
   * @param[in] theta parameter vector for the ODE.
   * @param[in] x continuous data vector for the ODE.
   * @param[in] x_int integer data vector for the ODE.
   * @param[in, out] msgs the print stream for warning messages.
   * @param[in] relative_tolerance relative tolerance passed to CVODE.
   * @param[in] absolute_tolerance absolute tolerance passed to CVODE.
   * @param[in] max_num_steps maximal number of admissable steps
   * between time-points
   * @return a vector of states, each state being a vector of the
   * same size as the state variable, corresponding to a time in ts.
   */
  template <typename F, typename T_initial, typename T_param, typename T_t0,
            typename T_ts>
  std::vector<std::vector<return_type_t<T_initial, T_param, T_t0, T_ts>>>
  integrate(const char* function_name, const F& f, const std::vector<T_initial>& y0, const T_t0& t0,
            const std::vector<T_ts>& ts, const std::vector<T_param>& theta,
            const std::vector<double>& x, const std::vector<int>& x_int,
            std::ostream* msgs, double relative_tolerance,
            double absolute_tolerance,
            long int max_num_steps) {  // NOLINT(runtime/int)
    using initial_var = stan::is_var<T_initial>;
    using param_var = stan::is_var<T_param>;

    const double t0_dbl = value_of(t0);
    const std::vector<double> ts_dbl = value_of(ts);

    check_finite(function_name, "initial state", y0);
    check_finite(function_name, "initial time", t0_dbl);
    check_finite(function_name, "times", ts_dbl);
    check_finite(function_name, "parameter vector", theta);
    check_finite(function_name, "continuous data", x);
    check_nonzero_size(function_name, "times", ts);
    check_nonzero_size(function_name, "initial state", y0);
    check_ordered(function_name, "times", ts_dbl);
    check_less(function_name, "initial time", t0_dbl, ts_dbl[0]);
    if (relative_tolerance <= 0) {
      invalid_argument(function_name, "relative_tolerance,", relative_tolerance, "",
                       ", must be greater than 0");
    }
    if (absolute_tolerance <= 0) {
      invalid_argument(function_name, "absolute_tolerance,", absolute_tolerance, "",
                       ", must be greater than 0");
    }
    if (max_num_steps <= 0) {
      invalid_argument(function_name, "max_num_steps,", max_num_steps, "",
                       ", must be greater than 0");
    }

    const size_t N = y0.size();
    const size_t M = theta.size();
    const size_t S = (initial_var::value ? N : 0) + (param_var::value ? M : 0);

    using ode_data = cvodes_ode_data<F, T_initial, T_param>;
    ode_data cvodes_data(f, y0, theta, x, x_int, msgs);

    void* cvodes_mem = CVodeCreate(Lmm);
    if (cvodes_mem == nullptr) {
      throw std::runtime_error("CVodeCreate failed to allocate memory");
    }

    const size_t coupled_size = cvodes_data.coupled_ode_.size();

    std::vector<std::vector<return_type_t<T_initial, T_param, T_t0, T_ts>>> y;
    coupled_ode_observer<F, T_initial, T_param, T_t0, T_ts> observer(
        f, y0, theta, t0, ts, x, x_int, msgs, y);

    try {
      check_flag_sundials(CVodeInit(cvodes_mem, &ode_data::cv_rhs, t0_dbl,
                                    cvodes_data.nv_state_),
                          "CVodeInit");

      // Assign pointer to this as user data
      check_flag_sundials(
          CVodeSetUserData(cvodes_mem, reinterpret_cast<void*>(&cvodes_data)),
          "CVodeSetUserData");

      cvodes_set_options(cvodes_mem, relative_tolerance, absolute_tolerance,
                         max_num_steps);

      // for the stiff solvers we need to reserve additional memory
      // and provide a Jacobian function call. new API since 3.0.0:
      // create matrix object and linear solver object; resource
      // (de-)allocation is handled in the cvodes_ode_data
      check_flag_sundials(
          CVodeSetLinearSolver(cvodes_mem, cvodes_data.LS_, cvodes_data.A_),
          "CVodeSetLinearSolver");
      check_flag_sundials(
          CVodeSetJacFn(cvodes_mem, &ode_data::cv_jacobian_states),
          "CVodeSetJacFn");

      // initialize forward sensitivity system of CVODES as needed
      if (S > 0) {
        check_flag_sundials(
            CVodeSensInit(cvodes_mem, static_cast<int>(S), CV_STAGGERED,
                          &ode_data::cv_rhs_sens, cvodes_data.nv_state_sens_),
            "CVodeSensInit");

        check_flag_sundials(CVodeSensEEtolerances(cvodes_mem),
                            "CVodeSensEEtolerances");
      }

      double t_init = t0_dbl;
      for (size_t n = 0; n < ts.size(); ++n) {
        double t_final = ts_dbl[n];
        if (t_final != t_init) {
          int ret = CVode(cvodes_mem, t_final, cvodes_data.nv_state_, &t_init,
                          CV_NORMAL);

          if (ret == CV_TOO_MUCH_WORK) {
            throw_domain_error(function_name, "", t_final,
                               "Failed to integrate to next output time (",
                               ") in less than max_num_steps steps");
          }
        }
        if (S > 0) {
          check_flag_sundials(
              CVodeGetSens(cvodes_mem, &t_init, cvodes_data.nv_state_sens_),
              "CVodeGetSens");
        }
        observer(cvodes_data.coupled_state_, t_final);
        t_init = t_final;
      }
    } catch (const std::exception& e) {
      CVodeFree(&cvodes_mem);
      throw;
    }

    CVodeFree(&cvodes_mem);

    return y;
  }
};  // cvodes integrator

}  // namespace math
}  // namespace stan
#endif
<|endoftext|>


<commit_before><commit_msg>signedness fix<commit_after><|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperInputImageParameter.h"
#include "itksys/SystemTools.hxx"
#include "otbImageFileReader.h"
#include "itkCastImageFilter.h"
#include "otbImageToVectorImageCastFilter.h"
#include "otbWrapperTypes.h"

namespace otb
{
namespace Wrapper
{

InputImageParameter::InputImageParameter()
{
  this->SetName("Input Image");
  this->SetKey("in");
  m_FileName="";
  m_PreviousFileName="";
  this->ClearValue();
}

InputImageParameter::~InputImageParameter()
{
}

bool
InputImageParameter::SetFromFileName(const std::string& filename)
{
  // First clear previous file choosen
  this->ClearValue();

  // TODO : when the logger will be available, redirect the exception
  // in the logger (like what is done in MsgReporter)
  if (!filename.empty()
      && itksys::SystemTools::FileExists(filename.c_str()))
    {
    FloatVectorReaderType::Pointer reader = FloatVectorReaderType::New();
    reader->SetFileName(filename);
    try
      {
      reader->UpdateOutputInformation();
      }
    catch(itk::ExceptionObject & /*err*/)
      {
      return false;
      }

    // the specified filename is valid => store the value
    m_FileName = filename;
    SetActive(true);
    return true;
    }
  return false;
}

FloatVectorImageType*
InputImageParameter::GetImage()
{
  return this->GetImage<FloatVectorImageType>();
}

#define otbGetImageMacro(image)                       \
  image##Type *                                       \
  InputImageParameter::Get##image ()                  \
  {                                                   \
    return this->GetImage< image##Type > ();          \
  }

otbGetImageMacro(UInt8Image)
otbGetImageMacro(Int8Image);
otbGetImageMacro(UInt16Image);
otbGetImageMacro(Int16Image);
otbGetImageMacro(UInt32Image);
otbGetImageMacro(Int32Image);
otbGetImageMacro(FloatImage);
otbGetImageMacro(DoubleImage);

otbGetImageMacro(UInt8VectorImage);
otbGetImageMacro(Int8VectorImage);
otbGetImageMacro(UInt16VectorImage);
otbGetImageMacro(Int16VectorImage);
otbGetImageMacro(UInt32VectorImage);
otbGetImageMacro(Int32VectorImage);
otbGetImageMacro(FloatVectorImage);
otbGetImageMacro(DoubleVectorImage);

otbGetImageMacro(UInt8RGBImage);
otbGetImageMacro(UInt8RGBAImage);

template <class TOutputImage>
TOutputImage *
InputImageParameter::GetImage()
{
  // Used m_PreviousFileName because if not, when the user call twice GetImage,
  // it without changing the filename, it returns 2 different
  // image pointers
  // TODO : how do we deal with 2 GetImage with 2 defferent template???
  if( m_PreviousFileName!=m_FileName )
    {
    //////////////////////// Filename case:
    // 2 cases : the user set a filename vs. the user set an image
    if ( !m_FileName.empty() )
      {
      m_PreviousFileName = m_FileName;
      typedef otb::ImageFileReader<TOutputImage> ReaderType;
      typename ReaderType::Pointer reader = ReaderType::New();
      reader->SetFileName(m_FileName);
      try
        {
        reader->UpdateOutputInformation();
        }
      catch (itk::ExceptionObject &)
        {
        this->ClearValue();
        }

      m_Image = reader->GetOutput();
      m_Reader = reader;

      // Pay attention, don't return m_Image because it is a ImageBase...
      return reader->GetOutput();
      }
    //////////////////////// Image case:
    else
      {
      if (m_Image.IsNull())
        {
        itkExceptionMacro("No input image or filename detected...");
        }
      else
        {
        if (dynamic_cast<Int8ImageType*> (m_Image.GetPointer()))
          {
          return CastImage<Int8ImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt8ImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt8ImageType, TOutputImage> ();
          }
        else if (dynamic_cast<Int16ImageType*> (m_Image.GetPointer()))
          {
          return CastImage<Int16ImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt16ImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt16ImageType, TOutputImage> ();
          }
        else if (dynamic_cast<Int32ImageType*> (m_Image.GetPointer()))
          {
          return CastImage<Int32ImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt32ImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt32ImageType, TOutputImage> ();
          }
        else if (dynamic_cast<FloatImageType*> (m_Image.GetPointer()))
          {
          return CastImage<FloatImageType, TOutputImage> ();
          }
        else if (dynamic_cast<DoubleImageType*> (m_Image.GetPointer()))
          {
          return CastImage<DoubleImageType, TOutputImage> ();
          }
        else if (dynamic_cast<Int8VectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<Int8VectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt8VectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<Int16VectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<Int16VectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt16VectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt16VectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<Int32VectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<Int32VectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt32VectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt32VectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<FloatVectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<FloatVectorImageType, TOutputImage> ();
          }
        else if (dynamic_cast<DoubleVectorImageType*> (m_Image.GetPointer()))
          {
          return CastImage<DoubleVectorImageType, TOutputImage> ();
          }

        else if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt8RGBAImageType, TOutputImage> ();
          }
        else if (dynamic_cast<UInt8RGBImageType*> (m_Image.GetPointer()))
          {
          return CastImage<UInt8RGBImageType, TOutputImage> ();
          }
        else
          {
          itkExceptionMacro("Unknown image type");
          }
        }
      }
    }
}

template <class TInputImage, class TOutputImage>
TOutputImage*
InputImageParameter::SimpleCastImage()
{
  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());

  typedef itk::CastImageFilter<TInputImage, TOutputImage> CasterType;
  typename CasterType::Pointer caster = CasterType::New();

  caster->SetInput(realInputImage);
  caster->UpdateOutputInformation();

  m_Image = caster->GetOutput();
  m_Caster = caster;

  return caster->GetOutput();
}

template <class TInputImage, class TOutputImage>
TOutputImage*
InputImageParameter::CastVectorImageFromImage()
{
  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());

  typedef ImageToVectorImageCastFilter<TInputImage, TOutputImage> CasterType;
  typename CasterType::Pointer caster = CasterType::New();

  caster->SetInput(realInputImage);
  caster->UpdateOutputInformation();

  m_Image = caster->GetOutput();
  m_Caster = caster;

  return caster->GetOutput();
}

#define otbCastImageMacro(InputImageType, OutputImageType, theMethod)   \
  template<> OutputImageType *                                          \
  InputImageParameter::CastImage<InputImageType , OutputImageType>()    \
  {                                                                     \
    return this->theMethod<InputImageType , OutputImageType>();         \
  }

#define otbGenericCastImageMacro(InputImageType, theMethod, prefix)     \
  otbCastImageMacro(InputImageType, UInt8##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Int8##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, UInt16##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Int16##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, UInt32##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Int32##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Float##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Double##prefix##ImageType, theMethod)

/*********************************************************************
********************** Image -> Image
**********************************************************************/
otbCastImageMacro(Int8ImageType, Int8ImageType, SimpleCastImage )

otbGenericCastImageMacro(UInt8ImageType, SimpleCastImage, )
otbGenericCastImageMacro(Int16ImageType, SimpleCastImage, )
otbGenericCastImageMacro(UInt16ImageType, SimpleCastImage, )
otbGenericCastImageMacro(Int32ImageType, SimpleCastImage, )
otbGenericCastImageMacro(UInt32ImageType, SimpleCastImage, )
otbGenericCastImageMacro(FloatImageType, SimpleCastImage, )
otbGenericCastImageMacro(DoubleImageType, SimpleCastImage, )

/*********************************************************************
********************** VectorImage -> VectorImage
**********************************************************************/
otbGenericCastImageMacro(Int8VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(UInt8VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(Int16VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(UInt16VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(Int32VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(UInt32VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(FloatVectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(DoubleVectorImageType, SimpleCastImage, Vector)

/*********************************************************************
********************** Image -> VectorImage
**********************************************************************/
otbGenericCastImageMacro(Int8ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(UInt8ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(Int16ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(UInt16ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(Int32ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(UInt32ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(FloatImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(DoubleImageType, CastVectorImageFromImage, Vector)

void
InputImageParameter::SetImage(FloatVectorImageType* image)
{
  this->SetImage<FloatVectorImageType>( image );
}

template <class TInputImage>
void
InputImageParameter::SetImage(TInputImage* image)
{
  m_Image = image;
}

bool
InputImageParameter::HasValue() const
{
  if( m_FileName.empty() && m_Image.IsNull() )
    return false;
  else
    return true;
}

void
InputImageParameter::ClearValue()
{
 m_Image  = NULL;
 m_Reader = NULL;
 m_Caster = NULL;
 m_FileName = "";
 m_PreviousFileName="";
}

}
}

<commit_msg>BUG: add-on to the fix for GetImage_called_twice<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperInputImageParameter.h"
#include "itksys/SystemTools.hxx"
#include "otbImageFileReader.h"
#include "itkCastImageFilter.h"
#include "otbImageToVectorImageCastFilter.h"
#include "otbWrapperTypes.h"

namespace otb
{
namespace Wrapper
{

InputImageParameter::InputImageParameter()
{
  this->SetName("Input Image");
  this->SetKey("in");
  m_FileName="";
  m_PreviousFileName="";
  this->ClearValue();
}

InputImageParameter::~InputImageParameter()
{
}

bool
InputImageParameter::SetFromFileName(const std::string& filename)
{
  // First clear previous file choosen
  this->ClearValue();

  // TODO : when the logger will be available, redirect the exception
  // in the logger (like what is done in MsgReporter)
  if (!filename.empty()
      && itksys::SystemTools::FileExists(filename.c_str()))
    {
    FloatVectorReaderType::Pointer reader = FloatVectorReaderType::New();
    reader->SetFileName(filename);
    try
      {
      reader->UpdateOutputInformation();
      }
    catch(itk::ExceptionObject & /*err*/)
      {
      return false;
      }

    // the specified filename is valid => store the value
    m_FileName = filename;
    SetActive(true);
    return true;
    }
  return false;
}

FloatVectorImageType*
InputImageParameter::GetImage()
{
  return this->GetImage<FloatVectorImageType>();
}

#define otbGetImageMacro(image)                       \
  image##Type *                                       \
  InputImageParameter::Get##image ()                  \
  {                                                   \
    return this->GetImage< image##Type > ();          \
  }

otbGetImageMacro(UInt8Image)
otbGetImageMacro(Int8Image);
otbGetImageMacro(UInt16Image);
otbGetImageMacro(Int16Image);
otbGetImageMacro(UInt32Image);
otbGetImageMacro(Int32Image);
otbGetImageMacro(FloatImage);
otbGetImageMacro(DoubleImage);

otbGetImageMacro(UInt8VectorImage);
otbGetImageMacro(Int8VectorImage);
otbGetImageMacro(UInt16VectorImage);
otbGetImageMacro(Int16VectorImage);
otbGetImageMacro(UInt32VectorImage);
otbGetImageMacro(Int32VectorImage);
otbGetImageMacro(FloatVectorImage);
otbGetImageMacro(DoubleVectorImage);

otbGetImageMacro(UInt8RGBImage);
otbGetImageMacro(UInt8RGBAImage);

template <class TOutputImage>
TOutputImage *
InputImageParameter::GetImage()
{
  // Used m_PreviousFileName because if not, when the user call twice GetImage,
  // it without changing the filename, it returns 2 different
  // image pointers
  // TODO : how do we deal with 2 GetImage with 2 defferent template???
  // Should be handled by the CastImage< > macro

  // 2 cases : the user set a filename vs. the user set an image
  if( m_PreviousFileName!=m_FileName && !m_FileName.empty() )
    {
    //////////////////////// Filename case:
    m_PreviousFileName = m_FileName;
    typedef otb::ImageFileReader<TOutputImage> ReaderType;
    typename ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(m_FileName);
    try
      {
      reader->UpdateOutputInformation();
      }
    catch (itk::ExceptionObject &)
      {
      this->ClearValue();
      }

    m_Image = reader->GetOutput();
    m_Reader = reader;

    // Pay attention, don't return m_Image because it is a ImageBase...
    return reader->GetOutput();
    }
  else
    {
    //////////////////////// Image case:
    if (m_Image.IsNull())
      {
      itkExceptionMacro("No input image or filename detected...");
      }
    else
      {
      if (dynamic_cast<Int8ImageType*> (m_Image.GetPointer()))
        {
        return CastImage<Int8ImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt8ImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt8ImageType, TOutputImage> ();
        }
      else if (dynamic_cast<Int16ImageType*> (m_Image.GetPointer()))
        {
        return CastImage<Int16ImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt16ImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt16ImageType, TOutputImage> ();
        }
      else if (dynamic_cast<Int32ImageType*> (m_Image.GetPointer()))
        {
        return CastImage<Int32ImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt32ImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt32ImageType, TOutputImage> ();
        }
      else if (dynamic_cast<FloatImageType*> (m_Image.GetPointer()))
        {
        return CastImage<FloatImageType, TOutputImage> ();
        }
      else if (dynamic_cast<DoubleImageType*> (m_Image.GetPointer()))
        {
        return CastImage<DoubleImageType, TOutputImage> ();
        }
      else if (dynamic_cast<Int8VectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<Int8VectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt8VectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<Int16VectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<Int16VectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt16VectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt16VectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<Int32VectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<Int32VectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt32VectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt32VectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<FloatVectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<FloatVectorImageType, TOutputImage> ();
        }
      else if (dynamic_cast<DoubleVectorImageType*> (m_Image.GetPointer()))
        {
        return CastImage<DoubleVectorImageType, TOutputImage> ();
        }

      else if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt8RGBAImageType, TOutputImage> ();
        }
      else if (dynamic_cast<UInt8RGBImageType*> (m_Image.GetPointer()))
        {
        return CastImage<UInt8RGBImageType, TOutputImage> ();
        }
      else
        {
        itkExceptionMacro("Unknown image type");
        }
      }
    }

}

template <class TInputImage, class TOutputImage>
TOutputImage*
InputImageParameter::SimpleCastImage()
{
  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());

  typedef itk::CastImageFilter<TInputImage, TOutputImage> CasterType;
  typename CasterType::Pointer caster = CasterType::New();

  caster->SetInput(realInputImage);
  caster->UpdateOutputInformation();

  m_Image = caster->GetOutput();
  m_Caster = caster;

  return caster->GetOutput();
}

template <class TInputImage, class TOutputImage>
TOutputImage*
InputImageParameter::CastVectorImageFromImage()
{
  TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer());

  typedef ImageToVectorImageCastFilter<TInputImage, TOutputImage> CasterType;
  typename CasterType::Pointer caster = CasterType::New();

  caster->SetInput(realInputImage);
  caster->UpdateOutputInformation();

  m_Image = caster->GetOutput();
  m_Caster = caster;

  return caster->GetOutput();
}

#define otbCastImageMacro(InputImageType, OutputImageType, theMethod)   \
  template<> OutputImageType *                                          \
  InputImageParameter::CastImage<InputImageType , OutputImageType>()    \
  {                                                                     \
    return this->theMethod<InputImageType , OutputImageType>();         \
  }

#define otbGenericCastImageMacro(InputImageType, theMethod, prefix)     \
  otbCastImageMacro(InputImageType, UInt8##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Int8##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, UInt16##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Int16##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, UInt32##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Int32##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Float##prefix##ImageType, theMethod) \
  otbCastImageMacro(InputImageType, Double##prefix##ImageType, theMethod)

/*********************************************************************
********************** Image -> Image
**********************************************************************/
otbCastImageMacro(Int8ImageType, Int8ImageType, SimpleCastImage )

otbGenericCastImageMacro(UInt8ImageType, SimpleCastImage, )
otbGenericCastImageMacro(Int16ImageType, SimpleCastImage, )
otbGenericCastImageMacro(UInt16ImageType, SimpleCastImage, )
otbGenericCastImageMacro(Int32ImageType, SimpleCastImage, )
otbGenericCastImageMacro(UInt32ImageType, SimpleCastImage, )
otbGenericCastImageMacro(FloatImageType, SimpleCastImage, )
otbGenericCastImageMacro(DoubleImageType, SimpleCastImage, )

/*********************************************************************
********************** VectorImage -> VectorImage
**********************************************************************/
otbGenericCastImageMacro(Int8VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(UInt8VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(Int16VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(UInt16VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(Int32VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(UInt32VectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(FloatVectorImageType, SimpleCastImage, Vector)
otbGenericCastImageMacro(DoubleVectorImageType, SimpleCastImage, Vector)

/*********************************************************************
********************** Image -> VectorImage
**********************************************************************/
otbGenericCastImageMacro(Int8ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(UInt8ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(Int16ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(UInt16ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(Int32ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(UInt32ImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(FloatImageType, CastVectorImageFromImage, Vector)
otbGenericCastImageMacro(DoubleImageType, CastVectorImageFromImage, Vector)

void
InputImageParameter::SetImage(FloatVectorImageType* image)
{
  this->SetImage<FloatVectorImageType>( image );
}

template <class TInputImage>
void
InputImageParameter::SetImage(TInputImage* image)
{
  m_Image = image;
}

bool
InputImageParameter::HasValue() const
{
  if( m_FileName.empty() && m_Image.IsNull() )
    return false;
  else
    return true;
}

void
InputImageParameter::ClearValue()
{
 m_Image  = NULL;
 m_Reader = NULL;
 m_Caster = NULL;
 m_FileName = "";
 m_PreviousFileName="";
}

}
}

<|endoftext|>