/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/*
* MatrixContentSymmetricUnitTest.cpp
*
* Created on: Jan 8, 2010
* Author: heber
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
using namespace std;
#include
#include
#include
#include "MatrixContentSymmetricUnitTest.hpp"
#include "MatrixContent.hpp"
#ifdef HAVE_TESTRUNNER
#include "UnitTestMain.hpp"
#endif /*HAVE_TESTRUNNER*/
/********************************************** Test classes **************************************/
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( MatrixContentSymmetricTest );
void MatrixContentSymmetricTest::setUp()
{
m = new MatrixContent(3,3);
};
void MatrixContentSymmetricTest::tearDown()
{
delete(m);
};
/** Unit Test for accessing matrix elements.
*
*/
void MatrixContentSymmetricTest::AccessTest()
{
// check whether all elements are initially zero
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
// set
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
m->set(i,j, i*3+j );
// and check
double *ptr = NULL;
for (int i=0;i<3;i++)
for (int j=0;j<3;j++) {
CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), m->at(i,j) );
ptr = m->Pointer(i,j);
CPPUNIT_ASSERT_EQUAL( (double)(i*3+j), *ptr );
}
// assignment
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
m->set(i,j, i*3+j );
MatrixContent *dest = new MatrixContent(3,3);
*dest = *m;
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( dest->at(i,j), m->at(i,j) );
delete(dest);
// out of bounds
//CPPUNIT_ASSERT_EQUAL(0., v->at(4,2) );
//CPPUNIT_ASSERT_EQUAL(0., v->at(2,17) );
//CPPUNIT_ASSERT_EQUAL(0., v->at(1024,140040) );
//CPPUNIT_ASSERT_EQUAL(0., v->at(-1,0) );
//CPPUNIT_ASSERT_EQUAL(0., v->at(0,-1) );
//CPPUNIT_ASSERT_EQUAL(0., v->at(-1,-1) );
};
/** Unit Test for initializating matrices.
*
*/
void MatrixContentSymmetricTest::InitializationTest()
{
// set zero
m->setZero();
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( 0., m->at(i,j) );
// set all
m->setValue(1.5);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( 1.5, m->at(i,j) );
// set basis
m->setIdentity();
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
// set from array
double array[] = { 1., 0., 0.,
0., 1., 0.,
0., 0., 1. };
m->setFromDoubleArray(array);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( i == j ? 1. : 0. , m->at(i,j) );
};
/** Unit Test for copying matrices.
*
*/
void MatrixContentSymmetricTest::CopyTest()
{
// set basis
MatrixContent *dest = NULL;
for (int i=0;i<3;i++) {
m->setValue(i);
dest = new MatrixContent(m);
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( m->at(i,j) , dest->at(i,j) );
delete(dest);
}
};
/** Unit Test for exchanging rows and columns.
*
*/
void MatrixContentSymmetricTest::ExchangeTest()
{
// set to 1,1,1,2, ...
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
m->set(i,j, i+1 );
// swap such that nothing happens
m->SwapColumns(1,2);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
// swap two rows
m->SwapRows(1,2);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
switch (j) {
case 0:
CPPUNIT_ASSERT_EQUAL( 1., m->at(j,i) );
break;
case 1:
CPPUNIT_ASSERT_EQUAL( 3., m->at(j,i) );
break;
case 2:
CPPUNIT_ASSERT_EQUAL( 2., m->at(j,i) );
break;
default:
CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
}
// check that op is reversable
m->SwapRows(1,2);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( (double)i+1., m->at(i,j) );
// set to 1,2,3,1, ...
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
m->set(i,j, j+1. );
// swap such that nothing happens
m->SwapRows(0,2);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
// swap two columns
m->SwapColumns(0,2);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
switch (j) {
case 0:
CPPUNIT_ASSERT_EQUAL( 3., m->at(i,j) );
break;
case 1:
CPPUNIT_ASSERT_EQUAL( 2., m->at(i,j) );
break;
case 2:
CPPUNIT_ASSERT_EQUAL( 1., m->at(i,j) );
break;
default:
CPPUNIT_ASSERT_EQUAL( -1., m->at(i,j) );
}
// check that op is reversable
m->SwapColumns(0,2);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
CPPUNIT_ASSERT_EQUAL( (double)j+1., m->at(i,j) );
// set to 1,2,3, ...
MatrixContent *n = new MatrixContent(3,3);
for (int i=0;i<3;i++)
for (int j=0;j<3;j++) {
m->set(i,j, 3*i+j+1 );
n->set(i,j, 3*j+i+1 );
}
// transpose
MatrixContent res = (*m).transposed();
CPPUNIT_ASSERT( *n == res );
// second transpose
res.transpose();
CPPUNIT_ASSERT( *m == res );
delete n;
};
/** Unit Test for matrix properties.
*
*/
void MatrixContentSymmetricTest::PropertiesTest()
{
// is zero
m->setZero();
CPPUNIT_ASSERT_EQUAL( true, m->IsNull() );
CPPUNIT_ASSERT_EQUAL( false, m->IsPositive() );
CPPUNIT_ASSERT_EQUAL( false, m->IsNegative() );
CPPUNIT_ASSERT_EQUAL( true, m->IsNonNegative() );
// is positive
m->setValue(0.5);
CPPUNIT_ASSERT_EQUAL( false, m->IsNull() );
CPPUNIT_ASSERT_EQUAL( true, m->IsPositive() );
CPPUNIT_ASSERT_EQUAL( false, m->IsNegative() );
CPPUNIT_ASSERT_EQUAL( true, m->IsNonNegative() );
// is negative
m->setValue(-0.1);
CPPUNIT_ASSERT_EQUAL( false, m->IsNull() );
CPPUNIT_ASSERT_EQUAL( false, m->IsPositive() );
CPPUNIT_ASSERT_EQUAL( true, m->IsNegative() );
CPPUNIT_ASSERT_EQUAL( false, m->IsNonNegative() );
// is positive definite
double array[] = { 1., 0., 0.,
0., 1., 1.,
0., 0., 1. };
m->setFromDoubleArray(array);
CPPUNIT_ASSERT_EQUAL( true, m->IsPositiveDefinite() );
//determinant
m->setIdentity();
CPPUNIT_ASSERT_EQUAL( 1., m->Determinant() );
m->setZero();
CPPUNIT_ASSERT_EQUAL( 0., m->Determinant() );
m->set( 0, 0, 1.);
m->set( 1, 1, 1.);
m->set( 2, 1, 1.);
CPPUNIT_ASSERT_EQUAL( 0., m->Determinant() );
double array2[] = { 2., 0., 1.,
-3., 1., 1.,
1., 5.5, 1. };
m->setFromDoubleArray(array2);
CPPUNIT_ASSERT_EQUAL( -26.5, m->Determinant() );
};