From b94e27229184632f14d534710e834186fea3572c Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 9 Apr 2016 00:18:34 -0400 Subject: [PATCH] [Numerics] Fix invalid memory access in DenseMatrix::mult Results were incorrect for rectangular matrices --- src/numerics/DenseMatrix.cpp | 2 +- test/general/test_matrices.cpp | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/numerics/DenseMatrix.cpp b/src/numerics/DenseMatrix.cpp index 6a200e930c..a716e349b3 100644 --- a/src/numerics/DenseMatrix.cpp +++ b/src/numerics/DenseMatrix.cpp @@ -87,7 +87,7 @@ void DenseMatrix::mult(const double* b, double* prod) const { ct_dgemv(ctlapack::ColMajor, ctlapack::NoTranspose, static_cast(nRows()), - static_cast(nRows()), 1.0, ptrColumn(0), + static_cast(nColumns()), 1.0, ptrColumn(0), static_cast(nRows()), b, 1, 0.0, prod, 1); } diff --git a/test/general/test_matrices.cpp b/test/general/test_matrices.cpp index 292ff74230..b7a140a7f0 100644 --- a/test/general/test_matrices.cpp +++ b/test/general/test_matrices.cpp @@ -1,5 +1,6 @@ #include "gtest/gtest.h" #include "cantera/numerics/BandMatrix.h" +#include "cantera/numerics/DenseMatrix.h" using namespace Cantera; @@ -103,3 +104,49 @@ TEST_F(BandMatrixTest, checkRowsColumns) { EXPECT_EQ((size_t) 0, i); EXPECT_DOUBLE_EQ(1, s); } + +class DenseMatrixTest : public testing::Test +{ +public: + DenseMatrixTest() + : x4{1,2,3,4} + , x3{3,2,1} + , b1{14, 32, 66, -34} + , b2{-6, 4, 26, 2} + , b3{14, 32, 66} + { + A1.resize(4, 4); // square + A2.resize(4, 3); // more rows + A3.resize(3, 4); // more columns + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + A1(i,j) = A2(i,j) = A3(i,j) = i*i + 2*j*j + i*j - 3; + } + A1(3,i) = A2(3,i) = pow(-1, i); + A1(i,3) = A3(i,3) = pow(2, i); + } + A1(3,3) = -9; + } + + DenseMatrix A1, A2, A3; + vector_fp x4, x3; + vector_fp b1, b2, b3; +}; + +TEST_F(DenseMatrixTest, matrix_times_vector) +{ + vector_fp c(4, 0.0); + A1.mult(x4.data(), c.data()); + for (size_t i = 0; i < 4; i++) { + EXPECT_DOUBLE_EQ(b1[i], c[i]); + } + A2.mult(x3.data(), c.data()); + for (size_t i = 0; i < 4; i++) { + EXPECT_DOUBLE_EQ(b2[i], c[i]); + } + A3.mult(x4.data(), c.data()); + for (size_t i = 0; i < 3; i++) { + EXPECT_DOUBLE_EQ(b3[i], c[i]); + } +}