Gromulus-Romulus
Gromulus-Romulus

Reputation: 165

Problem with Eigen natural log function: "implicit instantiation of undefined template"

I am working on a chemistry simulation that uses Eigen for calculations involving linear algebra.

Here is my code for determining gibbs free energy yield given a current vector of substrate concentrations:

#define R 8.314   // Gas constant - J mol^-1 K^-1
#define T 298.0   // Temperature - K

typedef Eigen::MatrixXf Matrix;
typedef Eigen::VectorXf Vector;

Vector calculateGibbs(Vector C, Matrix S, Vector F) {
    /** Calculate value of G vector based on current
        concentration vector C, stoichiometric matrix S, temperature T,
        and standard ∆G˚ vector F.

            Formula Used: G = S^t * (F + RT ln C)

        Where R is the universal gas constant (see line 16),
        and S^t is the transpose of S.
    */
    double RT = R * T;
    return S.transpose() * (F + RT * C.log());
}

When I try to compile code that calls this function, I get the following error:

error: implicit instantiation of
      undefined template 'Eigen::MatrixLogarithmReturnValue<Eigen::Matrix<float,
      -1, 1, 0, -1, 1> >'
    return S.transpose() * (F + RT * C.log());
                                       ^
/usr/local/include/eigen3/Eigen/src/Core/util/ForwardDeclarations.h:287:34: note: 
      template is declared here
template<typename Derived> class MatrixLogarithmReturnValue

Not sure what I'm doing wrong. Here is the documentation for the natural logarithm function I am referencing: https://eigen.tuxfamily.org/dox/group__CoeffwiseMathFunctions.html.

Can anyone clarify what I'm doing wrong? Any help is greatly appreciated.

EDIT: To be clear, my goal is to figure out how to take the natural log of a vector using the Eigen framework.

Upvotes: 0

Views: 907

Answers (2)

RHertel
RHertel

Reputation: 23818

Most of Eigen's coefficient-wise operations, including .log(), refer to Array objects. The coefficient-wise log operation cannot be applied to the Matrix type used in your example (or to the Vector typedef, which is just a special case of Matrix).

Using .array() and .matrix() makes it possible to switch between the types. In your case the returned value could be:

return S.transpose() * (F.array() + RT * C.array().log()).matrix();

or, equivalently,

return S.transpose() * (F + RT * C.array().log().matrix());

Upvotes: 2

Gromulus-Romulus
Gromulus-Romulus

Reputation: 165

Here's the solution!

A better way to make matrix - log operations in Eigen?

I needed to convert the C vector to an array, call the log method, then convert it back to a matrix! Vector addition still worked in the end since in Eigen vectors are a subclass of a matrix (unlike numpy, which differentiates between N-dimensional arrays and 1xN dimensional arrays).

Upvotes: 0

Related Questions