// Copyright (c) 2013-2020, SIB - Swiss Institute of Bioinformatics and
//                          Biozentrum - University of Basel
// 
// 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.


#ifndef PROMOD3_EIGEN_TYPES_HH
#define PROMOD3_EIGEN_TYPES_HH

#include <ost/base.hh>
#include <ost/geom/vecmat3_op.hh>

#include <Eigen/Dense>
#include <Eigen/StdVector>

namespace promod3 { namespace core {

// some quadratic matrices
typedef Eigen::Matrix<Real,3,3> EMat3;
typedef Eigen::Matrix<Real,4,4> EMat4;
typedef Eigen::Matrix<double,8,8> EMat8;
typedef Eigen::Matrix<double,16,16> EMat16;

typedef Eigen::Matrix<Real,3,1> EVec3;
typedef Eigen::Matrix<Real,4,1> EVec4;
typedef Eigen::Matrix<Real,Eigen::Dynamic,1> EVecX;

typedef Eigen::Matrix<Real,1,3> ERVec3;
typedef Eigen::Matrix<Real,1,4> ERVec4;
typedef Eigen::Matrix<Real,1,Eigen::Dynamic> ERVecX;

// some special matrices used at various locations
typedef Eigen::Matrix<Real,Eigen::Dynamic,3> EMatX3;
typedef Eigen::Matrix<Real,3,Eigen::Dynamic> EMat3X;
typedef Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> EMatXX; 
typedef Eigen::Matrix<double,16,3> EMat16_3;


// If you want to use stl containers of fixed sized Eigentype (e.g. EMatX3)
// you must use a custom allocator provided by Eigen to ensure proper memory
// alignment (more on that in the Eigen documentation)
typedef std::vector<EMatX3,Eigen::aligned_allocator<EMatX3> > EMatX3List;
typedef std::vector<EMatX3,Eigen::aligned_allocator<EMat3X> > EMat3XList;

// Fill row of given Eigen Matrix with 3 entries of Vec3
// NOTE: this is 60% faster than "tst.row(row) = core::ERVec3(&v[0]);"
template <typename EMat>
inline void EMatFillRow(EMat& mat, uint row, const geom::Vec3& v) {
  mat(row, 0) = v[0];
  mat(row, 1) = v[1];
  mat(row, 2) = v[2];
}

// Same for col
template <typename EMat>
inline void EMatFillCol(EMat& mat, uint col, const geom::Vec3& v) {
  mat(0, col) = v[0];
  mat(1, col) = v[1];
  mat(2, col) = v[2];
}

}} // ns

#endif
