Reputation: 165
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
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
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