#ifndef RANDOM_AFFINE_LAYER_HPP_
#define RANDOM_AFFINE_LAYER_HPP_

#include <boost/shared_ptr.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>

#include <cmath>

#include "caffe/blob.hpp"
#include "caffe/common.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"

namespace caffe {

template <typename Dtype>
class RandomAffineLayer: public Layer<Dtype> {

public:
	explicit RandomAffineLayer(const LayerParameter& param): Layer<Dtype>(param) {      }

	virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top);
	virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top);

	virtual inline const char* type() const { return "RandomAffine"; }
	virtual inline int MaxBottomBlobs() const { return 1; }
	virtual inline int ExactNumTopBlobs() const { return 1; }

protected:
	virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top);
	virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top);
	virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);
	virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);

private:
	Blob<Dtype> translation_x;
	Blob<Dtype> translation_y;
	Blob<Dtype> rotation;
	Blob<Dtype> scale;
	Blob<Dtype> flipping_rand;

	Blob<Dtype> t1_;
	Blob<Dtype> t2_;
	Blob<Dtype> t3_;

	Blob<Dtype> bottomExpanded;
	Blob<Dtype> t4_;
};

}  // namespace caffe

#endif  // CAFFE_COMMON_HPP_


// Copyright 2006. Peter Gottschling, Matthias Troyer, Rolf Bonderer

#ifndef LA_ETS_CONCEPTS_INCLUDE
#define LA_ETS_CONCEPTS_INCLUDE

#include <boost/numeric/linear_algebra/concepts.hpp>

#ifdef  __GXX_CONCEPTS__

//"Namespace ETS = Expression Templates Support":
// This file contains concepts that support the concepts defined in the namespace math.
// They are required since the math-concepts do not support ExpressionTemplates so far.
// The list of valid expressions is in fact infinite, so we just name some of them.
// Once ExpressionTemplates are supported by the math-concepts, the ets-concepts are no longer required.

namespace ets {

  auto concept Field<typename Element>
  {
    requires std::Assignable<Element, math::AdditivePartiallyInvertibleMonoid<Element>::unary_result_type>; //"x=-y" valid
  };

  auto concept VectorSpace<typename Vector, typename Scalar>
  {
    // valid expression: "vector2 += scalar*vector1"
    typename res_type_1;
    res_type_1 operator+=(Vector&, math::Multiplicable<Scalar, Vector>::result_type);

    // valid expression: "vector2 -= scalar*vector1"
    typename res_type_2;
    res_type_2 operator-=(Vector&, math::Multiplicable<Scalar, Vector>::result_type);

    //valid expression: "vector *= -scalar"
    typename res_type_3;
    res_type_3 operator*=(Vector&, const math::AdditivePartiallyInvertibleMonoid<Scalar>::unary_result_type&);

    //valid expression: "vector3 = vector1 + scalar*vector2"
    requires math::Addable<Vector, math::Multiplicable<Scalar, Vector>::result_type>; //"vector1+scalar*vector2" valid
    requires std::Assignable<Vector, math::Addable<Vector, math::Multiplicable<Scalar, Vector>::result_type>::result_type>; //"vector3 = vector1 + scalar*vector2" valid

  };

} //namespace ets

#endif //__GXX_CONCEPTS__

#endif //LA_ETS_CONCEPTS_INCLUDE


// Copyright (C) 2013 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include <Eigen/Core>
#include <Eigen/Geometry>
#include <Eigen/SVD>
#include <glog/logging.h>
#include <cmath>

#include "gtest/gtest.h"

#include "theia/math/util.h"
#include "theia/util/random.h"
#include "theia/sfm/pose/eight_point_fundamental_matrix.h"
#include "theia/sfm/pose/fundamental_matrix_util.h"
#include "theia/sfm/pose/test_util.h"
#include "theia/sfm/triangulation/triangulation.h"
#include "theia/sfm/types.h"

namespace theia {
namespace {
using Eigen::AngleAxisd;
using Eigen::Matrix3d;
using Eigen::Quaterniond;
using Eigen::Vector2d;
using Eigen::Vector3d;
using Eigen::Vector4d;

// Creates a test scenario from ground truth 3D points and ground truth rotation
// and translation. Projection (i.e., image) noise is optional (set to 0 for no
// noise). The fundamental matrix is computed to ensure that the reprojection
// errors are sufficiently small.
void GenerateImagePoints(const std::vector<Vector3d>& points_3d,
                         const double projection_noise_std_dev,
                         const Quaterniond& expected_rotation,
                         const Vector3d& expected_translation,
                         std::vector<Vector2d>* image_1_points,
                         std::vector<Vector2d>* image_2_points) {
  image_1_points->reserve(points_3d.size());
  image_2_points->reserve(points_3d.size());
  for (int i = 0; i < points_3d.size(); i++) {
    image_1_points->push_back(points_3d[i].hnormalized());
    image_2_points->push_back((expected_rotation * points_3d[i] +
                               expected_translation).hnormalized());
  }

  if (projection_noise_std_dev) {
    for (int i = 0; i < points_3d.size(); i++) {
      AddNoiseToProjection(projection_noise_std_dev, &((*image_1_points)[i]));
      AddNoiseToProjection(projection_noise_std_dev, &((*image_2_points)[i]));
    }
  }
}

// Check that the reprojection error is small.
void CheckReprojectionError(const std::vector<Vector2d>& image_1_points,
                            const std::vector<Vector2d>& image_2_points,
                            const Matrix3d& fundamental_matrix,
                            const double max_reprojection_error) {
  // Compute the projection matrices.
  Matrix3x4d left_projection, right_projection;
  ProjectionMatricesFromFundamentalMatrix(fundamental_matrix.data(),
                                          right_projection.data(),
                                          left_projection.data());

  for (int i = 0; i < image_1_points.size(); i++) {
    // Triangulate the world point.
    Vector4d triangulated_point;
    CHECK(TriangulateDLT(left_projection, right_projection,
                         image_1_points[i], image_2_points[i],
                         &triangulated_point));
    const Vector3d left_point =
        left_projection * triangulated_point;
    const Vector3d right_point =
        right_projection * triangulated_point;

    // Compute reprojection error.
    const double img_1_error =
        (image_1_points[i] - left_point.hnormalized()).squaredNorm();
    const double img_2_error =
        (image_2_points[i] - right_point.hnormalized()).squaredNorm();

    EXPECT_LT(img_1_error, max_reprojection_error);
    EXPECT_LT(img_2_error, max_reprojection_error);
  }
}

void EightPointNormalizedWithNoiseTest(const std::vector<Vector3d>& points_3d,
                                       const double projection_noise_std_dev,
                                       const Quaterniond& expected_rotation,
                                       const Vector3d& expected_translation,
                                       const double kMaxReprojectionError) {
  InitRandomGenerator();
  std::vector<Vector2d> image_1_points;
  std::vector<Vector2d> image_2_points;
  GenerateImagePoints(points_3d, projection_noise_std_dev, expected_rotation,
                      expected_translation, &image_1_points, &image_2_points);
  // Compute fundamental matrix.
  Matrix3d fundamental_matrix;
  EXPECT_TRUE(NormalizedEightPointFundamentalMatrix(image_1_points,
                                                    image_2_points,
                                                    &fundamental_matrix));

  CheckReprojectionError(image_1_points, image_2_points, fundamental_matrix,
                         kMaxReprojectionError);
}

void BasicNormalizedTest() {
  const std::vector<Vector3d> points_3d = { Vector3d(-1.0, 3.0, 3.0),
                                            Vector3d(1.0, -1.0, 2.0),
                                            Vector3d(-1.0, 1.0, 2.0),
                                            Vector3d(2.0, 1.0, 3.0),
                                            Vector3d(-1.0, -3.0, 2.0),
                                            Vector3d(1.0, -2.0, 1.0),
                                            Vector3d(-1.0, 4.0, 2.0),
                                            Vector3d(-2.0, 2.0, 3.0)
  };

  const Quaterniond soln_rotation(
      AngleAxisd(DegToRad(13.0), Vector3d(0.0, 0.0, 1.0)));
  const Vector3d soln_translation(1.0, 0.5, 1.5);
  const double kNoise = 0.0 / 512.0;
  const double kMaxReprojectionError = 1e-12;

  EightPointNormalizedWithNoiseTest(
      points_3d, kNoise, soln_rotation, soln_translation,
      kMaxReprojectionError);
}

TEST(NormalizedEightPoint, BasicTest) {
  BasicNormalizedTest();
}

TEST(NormalizedEightPoint, MinimalNoiseTest) {
  const std::vector<Vector3d> points_3d = { Vector3d(-1.0, 3.0, 3.0),
                                            Vector3d(1.0, -1.0, 2.0),
                                            Vector3d(-1.0, 1.0, 2.0),
                                            Vector3d(2.0, 1.0, 3.0),
                                            Vector3d(-1.0, -3.0, 2.0),
                                            Vector3d(1.0, -2.0, 1.0),
                                            Vector3d(-1.0, 4.0, 2.0),
                                            Vector3d(-2.0, 2.0, 3.0)
  };

  const Quaterniond soln_rotation(
      AngleAxisd(DegToRad(13.0), Vector3d(0.0, 0.0, 1.0)));
  const Vector3d soln_translation(1.0, 0.5, 0.0);
  const double kNoise = 1.0 / 512.0;
  const double kMaxReprojectionError = 1e-4;

  EightPointNormalizedWithNoiseTest(points_3d, kNoise, soln_rotation,
                                    soln_translation, kMaxReprojectionError);
}

TEST(NormalizedEightPoint, OverconstrainedNoiseTest) {
  const std::vector<Vector3d> points_3d = { Vector3d(-1.0, 3.0, 3.0),
                                            Vector3d(1.0, -1.0, 2.0),
                                            Vector3d(-1.0, 1.0, 2.0),
                                            Vector3d(2.0, 1.0, 3.0),
                                            Vector3d(-1.0, -3.0, 2.0),
                                            Vector3d(1.0, -2.0, 1.0),
                                            Vector3d(-1.0, 4.0, 2.0),
                                            Vector3d(-2.0, 2.0, 3.0),
                                            Vector3d(-2.0, 4.0, 1.0),
                                            Vector3d(-2.0, 2.0, 2.0),
                                            Vector3d(-4.0, 3.0, 3.0),
  };

  const Quaterniond soln_rotation(
      AngleAxisd(DegToRad(13.0), Vector3d(0.0, 0.0, 1.0)));
  const Vector3d soln_translation(1.0, 0.5, 0.0);
  const double kNoise = 1.0 / 512.0;
  const double kMaxReprojectionError = 1e-4;

  EightPointNormalizedWithNoiseTest(points_3d, kNoise, soln_rotation,
                                    soln_translation, kMaxReprojectionError);
}

TEST(NormalizedEightPoint, DegenerateTest) {
  const std::vector<Vector3d> points_3d = { Vector3d(-1.0, 3.0, 3.0),
                                            Vector3d(-1.0, 3.0, 3.0),
                                            Vector3d(-1.0, 1.0, 2.0),
                                            Vector3d(2.0, 1.0, 3.0),
                                            Vector3d(-1.0, -3.0, 2.0),
                                            Vector3d(1.0, -2.0, 1.0),
                                            Vector3d(-1.0, 4.0, 2.0),
                                            Vector3d(-2.0, 2.0, 3.0)
  };

  const Quaterniond soln_rotation(
  AngleAxisd(DegToRad(13.0), Vector3d(0.0, 0.0, 1.0)));
  const Vector3d soln_translation(1.0, 0.5, 0.0);

  std::vector<Vector2d> image_1_points;
  std::vector<Vector2d> image_2_points;
  GenerateImagePoints(points_3d, 0.0, soln_rotation,
                      soln_translation, &image_1_points, &image_2_points);

  Matrix3d fundamental_matrix;
  EXPECT_FALSE(NormalizedEightPointFundamentalMatrix(image_1_points,
                                                     image_2_points,
                                                     &fundamental_matrix));
}

}  // namespace
}  // namespace theia


//[ TArray
///////////////////////////////////////////////////////////////////////////////
//  Copyright 2008 Eric Niebler. Distributed under the Boost
//  Software License, Version 1.0. (See accompanying file
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// This example constructs a mini-library for linear algebra, using
// expression templates to eliminate the need for temporaries when
// adding arrays of numbers. It duplicates the TArray example from
// PETE (http://www.codesourcery.com/pooma/download.html)

#include <iostream>
#include <boost/mpl/int.hpp>
#include <boost/proto/core.hpp>
#include <boost/proto/context.hpp>
namespace mpl = boost::mpl;
namespace proto = boost::proto;
using proto::_;

// This grammar describes which TArray expressions
// are allowed; namely, int and array terminals
// plus, minus, multiplies and divides of TArray expressions.
struct TArrayGrammar
  : proto::or_<
        proto::terminal< int >
      , proto::terminal< int[3] >
      , proto::plus< TArrayGrammar, TArrayGrammar >
      , proto::minus< TArrayGrammar, TArrayGrammar >
      , proto::multiplies< TArrayGrammar, TArrayGrammar >
      , proto::divides< TArrayGrammar, TArrayGrammar >
    >
{};

template<typename Expr>
struct TArrayExpr;

// Tell proto that in the TArrayDomain, all
// expressions should be wrapped in TArrayExpr<> and
// must conform to the TArrayGrammar
struct TArrayDomain
  : proto::domain<proto::generator<TArrayExpr>, TArrayGrammar>
{};

// Here is an evaluation context that indexes into a TArray
// expression, and combines the result.
struct TArraySubscriptCtx
  : proto::callable_context< TArraySubscriptCtx const >
{
    typedef int result_type;

    TArraySubscriptCtx(std::ptrdiff_t i)
      : i_(i)
    {}

    // Index array terminals with our subscript. Everything
    // else will be handled by the default evaluation context.
    int operator ()(proto::tag::terminal, int const (&data)[3]) const
    {
        return data[this->i_];
    }

    std::ptrdiff_t i_;
};

// Here is an evaluation context that prints a TArray expression.
struct TArrayPrintCtx
  : proto::callable_context< TArrayPrintCtx const >
{
    typedef std::ostream &result_type;

    TArrayPrintCtx() {}

    std::ostream &operator ()(proto::tag::terminal, int i) const
    {
        return std::cout << i;
    }

    std::ostream &operator ()(proto::tag::terminal, int const (&arr)[3]) const
    {
        return std::cout << '{' << arr[0] << ", " << arr[1] << ", " << arr[2] << '}';
    }

    template<typename L, typename R>
    std::ostream &operator ()(proto::tag::plus, L const &l, R const &r) const
    {
        return std::cout << '(' << l << " + " << r << ')';
    }

    template<typename L, typename R>
    std::ostream &operator ()(proto::tag::minus, L const &l, R const &r) const
    {
        return std::cout << '(' << l << " - " << r << ')';
    }

    template<typename L, typename R>
    std::ostream &operator ()(proto::tag::multiplies, L const &l, R const &r) const
    {
        return std::cout << l << " * " << r;
    }

    template<typename L, typename R>
    std::ostream &operator ()(proto::tag::divides, L const &l, R const &r) const
    {
        return std::cout << l << " / " << r;
    }
};

// Here is the domain-specific expression wrapper, which overrides
// operator [] to evaluate the expression using the TArraySubscriptCtx.
template<typename Expr>
struct TArrayExpr
  : proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain>
{
    typedef proto::extends<Expr, TArrayExpr<Expr>, TArrayDomain> base_type;

    TArrayExpr( Expr const & expr = Expr() )
      : base_type( expr )
    {}

    // Use the TArraySubscriptCtx to implement subscripting
    // of a TArray expression tree.
    int operator []( std::ptrdiff_t i ) const
    {
        TArraySubscriptCtx const ctx(i);
        return proto::eval(*this, ctx);
    }

    // Use the TArrayPrintCtx to display a TArray expression tree.
    friend std::ostream &operator <<(std::ostream &sout, TArrayExpr<Expr> const &expr)
    {
        TArrayPrintCtx const ctx;
        return proto::eval(expr, ctx);
    }
};

// Here is our TArray terminal, implemented in terms of TArrayExpr
// It is basically just an array of 3 integers.
struct TArray
  : TArrayExpr< proto::terminal< int[3] >::type >
{
    explicit TArray( int i = 0, int j = 0, int k = 0 )
    {
        (*this)[0] = i;
        (*this)[1] = j;
        (*this)[2] = k;
    }

    // Here we override operator [] to give read/write access to
    // the elements of the array. (We could use the TArrayExpr
    // operator [] if we made the subscript context smarter about
    // returning non-const reference when appropriate.)
    int &operator [](std::ptrdiff_t i)
    {
        return proto::value(*this)[i];
    }

    int const &operator [](std::ptrdiff_t i) const
    {
        return proto::value(*this)[i];
    }

    // Here we define a operator = for TArray terminals that
    // takes a TArray expression.
    template< typename Expr >
    TArray &operator =(Expr const & expr)
    {
        // proto::as_expr<TArrayDomain>(expr) is the same as
        // expr unless expr is an integer, in which case it
        // is made into a TArrayExpr terminal first.
        return this->assign(proto::as_expr<TArrayDomain>(expr));
    }

    template< typename Expr >
    TArray &printAssign(Expr const & expr)
    {
        *this = expr;
        std::cout << *this << " = " << expr << std::endl;
        return *this;
    }

private:
    template< typename Expr >
    TArray &assign(Expr const & expr)
    {
        // expr[i] here uses TArraySubscriptCtx under the covers.
        (*this)[0] = expr[0];
        (*this)[1] = expr[1];
        (*this)[2] = expr[2];
        return *this;
    }
};

int main()
{
    TArray a(3,1,2);

    TArray b;

    std::cout << a << std::endl;
    std::cout << b << std::endl;

    b[0] = 7; b[1] = 33; b[2] = -99;

    TArray c(a);

    std::cout << c << std::endl;

    a = 0;

    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;

    a = b + c;

    std::cout << a << std::endl;

    a.printAssign(b+c*(b + 3*c));

    return 0;
}
//]


#include <iostream>

#include <boost/safe_numerics/safe_integer_range.hpp>
#include <boost/safe_numerics/safe_integer_literal.hpp>
#include <boost/safe_numerics/exception.hpp>
#include <boost/safe_numerics/native.hpp>
#include "safe_format.hpp" // prints out range and value of any type

using namespace boost::safe_numerics;

// create a type for holding small integers in a specific range
using safe_t = safe_signed_range<
    -24,
    82,
    native,           // C++ type promotion rules work OK for this example
    loose_trap_policy // catch problems at compile time
>;

// create a type to hold one specific value
template<int I>
using const_safe_t = safe_signed_literal<I, native, loose_trap_policy>;

// We "know" that C++ type promotion rules will work such that
// addition will never overflow. If we change the program to break this,
// the usage of the loose_trap_policy promotion policy will prevent compilation.
int main(int, const char *[]){
    std::cout << "example 83:\n";

    constexpr const const_safe_t<10> x;
    std::cout << "x = " << safe_format(x) << std::endl;
    constexpr const const_safe_t<67> y;
    std::cout << "y = " << safe_format(y) << std::endl;
    const safe_t z = x + y;
    std::cout << "x + y = " << safe_format(x + y) << std::endl;
    std::cout << "z = " << safe_format(z) << std::endl;
    return 0;
}


//============================================================================
// Name         : dnageometries.hpp
// Author       : Roger Fraser
// Contributors :
// Version      : 1.00
// Copyright    : Copyright 2017 Geoscience Australia
//
//                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
//
//                Unless required by applicable law or agreed to in writing, software
//                distributed under the License is distributed on an "AS IS" BASIS,
//                WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//                See the License for the specific language governing permissions and
//                limitations under the License.
//
// Description  : Basic geometry point
//============================================================================

#ifndef DNAGEOMETRIES_H_
#define DNAGEOMETRIES_H_

#if defined(_MSC_VER)
	#if defined(LIST_INCLUDES_ON_BUILD)
		#pragma message("  " __FILE__)
	#endif
#endif

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/register/point.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>

using namespace std;
using namespace boost::geometry;

namespace dynadjust {
namespace geometries {

template <class T>
class dnaGeometryPoint
{
public:
	// dnaGeometryPoint()
	// 	: m_east_long(0.), m_north_lat(0.)
	// {}

	// dnaGeometryPoint(const T& east_long, const T& north_lat)
	// 	: m_east_long(east_long), m_north_lat(north_lat)
	// {}

	T get_east_long() const {
		return m_east_long;
	}

	T get_north_lat() const {
		return m_north_lat;
	}

	void set_east_long(T east_long) {
		m_east_long = east_long;
	}

	void set_north_lat(T north_lat) {
		m_north_lat = north_lat;
	}

private:

	T m_east_long;
	T m_north_lat;
};

typedef boost::geometry::model::polygon<dnaGeometryPoint <double>> dnaGeometryPolygon;
typedef boost::geometry::strategy::centroid::bashein_detmer<dnaGeometryPoint<double>, dnaGeometryPoint<double>> dnaBasheinStrategy;
typedef boost::geometry::strategy::centroid::average<dnaGeometryPoint<double>, dnaGeometryPoint<double>> dnaAverageStrategy;

}	// namespace geometries
}	// namespace dynadjust

BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(
	dynadjust::geometries::dnaGeometryPoint<double>,
	double,
	boost::geometry::cs::spherical_equatorial<boost::geometry::degree>,
	dynadjust::geometries::dnaGeometryPoint<double>::get_east_long,
	dynadjust::geometries::dnaGeometryPoint<double>::get_north_lat,
	dynadjust::geometries::dnaGeometryPoint<double>::set_east_long,
	dynadjust::geometries::dnaGeometryPoint<double>::set_north_lat)

#endif /* DNAGEOMETRIES_H_ */