=== modified file 'src/libmatrix/Makefile'
@@ -1,14 +1,31 @@
-TARGETS = libmatrix.a
-SRCS = mat.cc
-OBJS = $(SRCS:.cc=.o)
CXXFLAGS = -Wall -Werror -pedantic -O3
-
-default: $(TARGETS)
-
-mat.o : mat.cc mat.h
-
-libmatrix.a : mat.o mat.h stack.h vec.h
- $(AR) -r $@ $(OBJS)
-
+LIBMATRIX = libmatrix.a
+LIBSRCS = mat.cc program.cc
+LIBOBJS = $(LIBSRCS:.cc=.o)
+TESTDIR = test
+LIBMATRIX_TESTS = $(TESTDIR)/libmatrix_test
+TESTSRCS = $(TESTDIR)/options.cc \
+ $(TESTDIR)/inverse_test.cc \
+ $(TESTDIR)/libmatrix_test.cc
+TESTOBJS = $(TESTSRCS:.cc=.o)
+
+# Make sure to build both the library targets and the tests, and generate
+# a make failure if the tests don't pass.
+default: $(LIBMATRIX) $(LIBMATRIX_TESTS) run_tests
+
+# Main library targets here.
+mat.o : mat.cc mat.h vec.h
+program.o: program.cc program.h mat.h vec.h
+libmatrix.a : mat.o mat.h stack.h vec.h program.o program.h
+ $(AR) -r $@ $(LIBOBJS)
+
+# Tests and execution targets here.
+$(TESTDIR)/options.o: $(TESTDIR)/options.cc $(TESTDIR)/libmatrix_test.h
+$(TESTDIR)/libmatrix_test.o: $(TESTDIR)/libmatrix_test.cc $(TESTDIR)/libmatrix_test.h $(TESTDIR)/inverse_test.h
+$(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h
+$(TESTDIR)/libmatrix_test: $(TESTDIR)/options.o $(TESTDIR)/libmatrix_test.o $(TESTDIR)/inverse_test.o libmatrix.a
+ $(CXX) -o $@ $?
+run_tests: $(LIBMATRIX_TESTS)
+ $(LIBMATRIX_TESTS)
clean :
- $(RM) $(OBJS) $(TARGETS)
+ $(RM) $(LIBOBJS) $(TESTOBJS) $(LIBMATRIX) $(LIBMATRIX_TESTS)
=== modified file 'src/libmatrix/mat.h'
@@ -11,7 +11,7 @@
//
#ifndef MAT_H_
#define MAT_H_
-
+#include <stdexcept>
#include <iostream>
#include <iomanip>
#include "vec.h"
@@ -61,6 +61,13 @@
m_[2] = m.m_[2];
m_[3] = m.m_[3];
}
+ tmat2(const T& c0r0, const T& c0r1, const T& c1r0, const T& c1r1)
+ {
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c1r0;
+ m_[3] = c1r1;
+ }
~tmat2() {}
void setIdentity()
@@ -71,11 +78,35 @@
m_[3] = 1;
}
- void transpose()
+ tmat2& transpose()
{
T tmp_val = m_[1];
m_[1] = m_[2];
m_[2] = tmp_val;
+ return *this;
+ }
+
+ T determinant()
+ {
+ return (m_[0] * m_[3]) - (m_[2] * m_[1]);
+ }
+
+ tmat2& inverse() throw(std::runtime_error)
+ {
+ T d(determinant());
+ if (d == static_cast<T>(0))
+ {
+ throw std::runtime_error("Matrix is noninvertible!!!!");
+ }
+ T c0r0(m_[3] / d);
+ T c0r1(-m_[1] / d);
+ T c1r0(-m_[2] / d);
+ T c1r1(m_[0] / d);
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c1r0;
+ m_[3] = c1r1;
+ return *this;
}
void print() const
@@ -83,20 +114,33 @@
static const int precision(6);
// row 0
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][0];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][1];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
std::cout << " |" << std::endl;
// row 1
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][0];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][1];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
std::cout << " |" << std::endl;
}
operator const T*() const { return &m_[0];}
+ bool operator==(const tmat2& rhs) const
+ {
+ return m_[0] == rhs.m_[0] &&
+ m_[1] == rhs.m_[1] &&
+ m_[2] == rhs.m_[2] &&
+ m_[3] == rhs.m_[3];
+ }
+
+ bool operator!=(const tmat2& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
tmat2& operator=(const tmat2& rhs)
{
if (this != &rhs)
@@ -249,6 +293,20 @@
m_[7] = m.m_[7];
m_[8] = m.m_[8];
}
+ tmat3(const T& c0r0, const T& c0r1, const T& c0r2,
+ const T& c1r0, const T& c1r1, const T& c1r2,
+ const T& c2r0, const T& c2r1, const T& c2r2)
+ {
+ m_[0] = c0r0;
+ m_[1] = c0r1;
+ m_[2] = c0r2;
+ m_[3] = c1r0;
+ m_[4] = c1r1;
+ m_[5] = c1r2;
+ m_[6] = c2r0;
+ m_[7] = c2r1;
+ m_[8] = c2r2;
+ }
~tmat3() {}
void setIdentity()
@@ -264,7 +322,7 @@
m_[8] = 1;
}
- void transpose()
+ tmat3& transpose()
{
T tmp_val = m_[1];
m_[1] = m_[3];
@@ -275,6 +333,45 @@
tmp_val = m_[5];
m_[5] = m_[7];
m_[7] = tmp_val;
+ return *this;
+ }
+
+ T determinant()
+ {
+ tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
+ tmat2<T> minor3(m_[1], m_[2], m_[7], m_[8]);
+ tmat2<T> minor6(m_[1], m_[2], m_[4], m_[5]);
+ return (m_[0] * minor0.determinant()) -
+ (m_[3] * minor3.determinant()) +
+ (m_[6] * minor6.determinant());
+ }
+
+ tmat3& inverse() throw(std::runtime_error)
+ {
+ T d(determinant());
+ if (d == static_cast<T>(0))
+ {
+ throw std::runtime_error("Matrix is noninvertible!!!!");
+ }
+ tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
+ tmat2<T> minor1(m_[7], m_[8], m_[1], m_[2]);
+ tmat2<T> minor2(m_[1], m_[2], m_[4], m_[5]);
+ tmat2<T> minor3(m_[6], m_[8], m_[3], m_[5]);
+ tmat2<T> minor4(m_[0], m_[2], m_[6], m_[8]);
+ tmat2<T> minor5(m_[3], m_[5], m_[0], m_[2]);
+ tmat2<T> minor6(m_[3], m_[4], m_[6], m_[7]);
+ tmat2<T> minor7(m_[6], m_[7], m_[0], m_[1]);
+ tmat2<T> minor8(m_[0], m_[1], m_[3], m_[4]);
+ m_[0] = minor0.determinant() / d;
+ m_[1] = minor1.determinant() / d;
+ m_[2] = minor2.determinant() / d;
+ m_[3] = minor3.determinant() / d;
+ m_[4] = minor4.determinant() / d;
+ m_[5] = minor5.determinant() / d;
+ m_[6] = minor6.determinant() / d;
+ m_[7] = minor7.determinant() / d;
+ m_[8] = minor8.determinant() / d;
+ return *this;
}
void print() const
@@ -282,32 +379,50 @@
static const int precision(6);
// row 0
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][2];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6];
std::cout << " |" << std::endl;
// row 1
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][2];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7];
std::cout << " |" << std::endl;
// row 2
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][2];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8];
std::cout << " |" << std::endl;
}
operator const T*() const { return &m_[0];}
+ bool operator==(const tmat3& rhs) const
+ {
+ return m_[0] == rhs.m_[0] &&
+ m_[1] == rhs.m_[1] &&
+ m_[2] == rhs.m_[2] &&
+ m_[3] == rhs.m_[3] &&
+ m_[4] == rhs.m_[4] &&
+ m_[5] == rhs.m_[5] &&
+ m_[6] == rhs.m_[6] &&
+ m_[7] == rhs.m_[7] &&
+ m_[8] == rhs.m_[8];
+ }
+
+ bool operator!=(const tmat3& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
tmat3& operator=(const tmat3& rhs)
{
if (this != &rhs)
@@ -531,7 +646,7 @@
m_[15] = 1;
}
- void transpose()
+ tmat4& transpose()
{
T tmp_val = m_[1];
m_[1] = m_[4];
@@ -551,6 +666,64 @@
tmp_val = m_[11];
m_[11] = m_[14];
m_[14] = tmp_val;
+ return *this;
+ }
+
+ T determinant()
+ {
+ tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+ tmat3<T> minor4(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+ tmat3<T> minor8(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]);
+ tmat3<T> minor12(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[9], m_[10], m_[11]);
+ return (m_[0] * minor0.determinant()) -
+ (m_[4] * minor4.determinant()) +
+ (m_[8] * minor8.determinant()) -
+ (m_[12] * minor12.determinant());
+ }
+
+ tmat4& inverse() throw(std::runtime_error)
+ {
+ T d(determinant());
+ if (d == static_cast<T>(0))
+ {
+ throw std::runtime_error("Matrix is noninvertible!!!!");
+ }
+ tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
+ tmat3<T> minor1(m_[1], m_[2], m_[3], m_[13], m_[14], m_[15], m_[9], m_[10], m_[11]);
+ tmat3<T> minor2(m_[1], m_[2], m_[3], m_[5], m_[6], m_[7], m_[13], m_[14], m_[15]);
+ tmat3<T> minor3(m_[1], m_[2], m_[3], m_[9], m_[10], m_[11], m_[5], m_[6], m_[7]);
+
+ tmat3<T> minor4(m_[4], m_[6], m_[7], m_[12], m_[14], m_[15], m_[8], m_[10], m_[11]);
+ tmat3<T> minor5(m_[0], m_[2], m_[3], m_[8], m_[10], m_[11], m_[12], m_[14], m_[15]);
+ tmat3<T> minor6(m_[0], m_[2], m_[3], m_[12], m_[14], m_[15], m_[4], m_[6], m_[7]);
+ tmat3<T> minor7(m_[0], m_[2], m_[3], m_[4], m_[6], m_[7], m_[8], m_[10], m_[11]);
+
+ tmat3<T> minor8(m_[4], m_[5], m_[7], m_[8], m_[9], m_[11], m_[12], m_[13], m_[15]);
+ tmat3<T> minor9(m_[0], m_[1], m_[3], m_[12], m_[13], m_[15], m_[8], m_[9], m_[11]);
+ tmat3<T> minor10(m_[0], m_[1], m_[3], m_[4], m_[5], m_[7], m_[12], m_[13], m_[15]);
+ tmat3<T> minor11(m_[0], m_[1], m_[3], m_[8], m_[9], m_[11], m_[4], m_[5], m_[7]);
+
+ tmat3<T> minor12(m_[4], m_[5], m_[6], m_[12], m_[13], m_[14], m_[8], m_[9], m_[10]);
+ tmat3<T> minor13(m_[0], m_[1], m_[2], m_[8], m_[9], m_[10], m_[12], m_[13], m_[14]);
+ tmat3<T> minor14(m_[0], m_[1], m_[2], m_[12], m_[13], m_[14], m_[4], m_[5], m_[6]);
+ tmat3<T> minor15(m_[0], m_[1], m_[2], m_[4], m_[5], m_[6], m_[8], m_[9], m_[10]);
+ m_[0] = minor0.determinant() / d;
+ m_[1] = minor1.determinant() / d;
+ m_[2] = minor2.determinant() / d;
+ m_[3] = minor3.determinant() / d;
+ m_[4] = minor4.determinant() / d;
+ m_[5] = minor5.determinant() / d;
+ m_[6] = minor6.determinant() / d;
+ m_[7] = minor7.determinant() / d;
+ m_[8] = minor8.determinant() / d;
+ m_[9] = minor9.determinant() / d;
+ m_[10] = minor10.determinant() / d;
+ m_[11] = minor11.determinant() / d;
+ m_[12] = minor12.determinant() / d;
+ m_[13] = minor13.determinant() / d;
+ m_[14] = minor14.determinant() / d;
+ m_[15] = minor15.determinant() / d;
+ return *this;
}
void print() const
@@ -558,48 +731,73 @@
static const int precision(6);
// row 0
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][2];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0][3];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[0];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[4];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[8];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[12];
std::cout << " |" << std::endl;
// row 1
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][2];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1][3];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[1];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[5];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[9];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[13];
std::cout << " |" << std::endl;
// row 2
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][2];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2][3];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[2];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[6];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[10];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[14];
std::cout << " |" << std::endl;
// row 3
std::cout << "| ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][0];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][1];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][2];
- std::cout << " ";
- std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3][3];
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[3];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[7];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[11];
+ std::cout << " ";
+ std::cout << std::fixed << std::showpoint << std::setprecision(precision) << m_[15];
std::cout << " |" << std::endl;
}
operator const T*() const { return &m_[0];}
+ bool operator==(const tmat4& rhs) const
+ {
+ return m_[0] == rhs.m_[0] &&
+ m_[1] == rhs.m_[1] &&
+ m_[2] == rhs.m_[2] &&
+ m_[3] == rhs.m_[3] &&
+ m_[4] == rhs.m_[4] &&
+ m_[5] == rhs.m_[5] &&
+ m_[6] == rhs.m_[6] &&
+ m_[7] == rhs.m_[7] &&
+ m_[8] == rhs.m_[8] &&
+ m_[9] == rhs.m_[9] &&
+ m_[10] == rhs.m_[10] &&
+ m_[11] == rhs.m_[11] &&
+ m_[12] == rhs.m_[12] &&
+ m_[13] == rhs.m_[13] &&
+ m_[14] == rhs.m_[14] &&
+ m_[15] == rhs.m_[15];
+ }
+
+ bool operator!=(const tmat4& rhs) const
+ {
+ return !(*this == rhs);
+ }
+
tmat4& operator=(const tmat4& rhs)
{
if (this != &rhs)
=== renamed file 'src/program.cc' => 'src/libmatrix/program.cc'
@@ -1,33 +1,21 @@
-/*
- * Copyright © 2011 Linaro Limited
- *
- * This file is part of glcompbench.
- *
- * glcompbench 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 3 of the License, or
- * (at your option) any later version.
- *
- * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Jesse Barker <jesse.barker@linaro.org>
- */
-
+//
+// Copyright (c) 2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+// Alexandros Frantzis - local changes for better integration with glcompbench
+//
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
-
+#include <iostream>
#include "gl-headers.h"
-
#include "program.h"
#include "log.h"
=== renamed file 'src/program.h' => 'src/libmatrix/program.h'
@@ -1,26 +1,14 @@
-/*
- * Copyright © 2011 Linaro Limited
- *
- * This file is part of glcompbench.
- *
- * glcompbench 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 3 of the License, or
- * (at your option) any later version.
- *
- * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Jesse Barker <jesse.barker@linaro.org>
- */
-
+//
+// Copyright (c) 2011 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
#ifndef PROGRAM_H_
#define PROGRAM_H_
=== added directory 'src/libmatrix/test'
=== added file 'src/libmatrix/test/inverse_test.cc'
@@ -0,0 +1,161 @@
+#include <iostream>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
+#include "../mat.h"
+
+using LibMatrix::mat2;
+using LibMatrix::mat3;
+using LibMatrix::mat4;
+using std::cout;
+using std::endl;
+
+void
+MatrixTest2x2Inverse::run(const Options& options)
+{
+ mat2 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat2 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m[0][1] = -2.5;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl;
+ m.print();
+ }
+
+ mat2 mi(m);
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl;
+ mi.print();
+ }
+
+ mi.inverse();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Inverse of copy: " << endl << endl;
+ mi.print();
+ }
+
+ mat2 i = m * mi;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+ i.print();
+ }
+
+ mat2 ident;
+ if (i == ident)
+ {
+ pass_ = true;
+ }
+}
+
+void
+MatrixTest3x3Inverse::run(const Options& options)
+{
+ mat3 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat3 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m[1][2] = -2.5;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl;
+ m.print();
+ }
+
+ mat3 mi(m);
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl;
+ mi.print();
+ }
+
+ mi.inverse();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Inverse of copy: " << endl << endl;
+ mi.print();
+ }
+
+ mat3 i = m * mi;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+ i.print();
+ }
+
+ mat3 ident;
+ if (i == ident)
+ {
+ pass_ = true;
+ }
+}
+
+void
+MatrixTest4x4Inverse::run(const Options& options)
+{
+ mat4 m;
+
+ if (options.beVerbose())
+ {
+ cout << "Starting with mat4 (should be identity): " << endl << endl;
+ m.print();
+ }
+
+ m[2][3] = -2.5;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl;
+ m.print();
+ }
+
+ mat4 mi(m);
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl;
+ mi.print();
+ }
+
+ mi.inverse();
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Inverse of copy: " << endl << endl;
+ mi.print();
+ }
+
+ mat4 i = m * mi;
+
+ if (options.beVerbose())
+ {
+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
+ i.print();
+ }
+
+ mat4 ident;
+ if (i == ident)
+ {
+ pass_ = true;
+ }
+}
+
=== added file 'src/libmatrix/test/inverse_test.h'
@@ -0,0 +1,28 @@
+#ifndef INVERSE_TEST_H_
+#define INVERSE_TEST_H_
+
+class MatrixTest;
+class Options;
+
+class MatrixTest2x2Inverse : public MatrixTest
+{
+public:
+ MatrixTest2x2Inverse() : MatrixTest("mat2::inverse") {}
+ virtual void run(const Options& options);
+};
+
+class MatrixTest3x3Inverse : public MatrixTest
+{
+public:
+ MatrixTest3x3Inverse() : MatrixTest("mat3::inverse") {}
+ virtual void run(const Options& options);
+};
+
+class MatrixTest4x4Inverse : public MatrixTest
+{
+public:
+ MatrixTest4x4Inverse() : MatrixTest("mat4::inverse") {}
+ virtual void run(const Options& options);
+};
+
+#endif // INVERSE_TEST_H_
=== added file 'src/libmatrix/test/libmatrix_test.cc'
@@ -0,0 +1,57 @@
+//
+// Copyright (c) 2010 Linaro Limited
+//
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the MIT License which accompanies
+// this distribution, and is available at
+// http://www.opensource.org/licenses/mit-license.php
+//
+// Contributors:
+// Jesse Barker - original implementation.
+//
+#include <iostream>
+#include <string>
+#include <vector>
+#include "libmatrix_test.h"
+#include "inverse_test.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+int
+main(int argc, char** argv)
+{
+ Options testOptions("matrix_test");
+ testOptions.parseArgs(argc, argv);
+ if (testOptions.showHelp())
+ {
+ testOptions.printUsage();
+ return 0;
+ }
+
+ using std::vector;
+ vector<MatrixTest*> testVec;
+ testVec.push_back(new MatrixTest2x2Inverse());
+ testVec.push_back(new MatrixTest3x3Inverse());
+ testVec.push_back(new MatrixTest4x4Inverse());
+
+ for (vector<MatrixTest*>::iterator testIt = testVec.begin();
+ testIt != testVec.end();
+ testIt++)
+ {
+ MatrixTest* curTest = *testIt;
+ curTest->run(testOptions);
+ if (!curTest->passed())
+ {
+ cerr << curTest->name() << " does not work!" << endl;
+ return 1;
+ }
+ if (testOptions.beVerbose())
+ {
+ cout << curTest->name() << " is okay!" << endl;
+ }
+ }
+
+ return 0;
+}
=== added file 'src/libmatrix/test/libmatrix_test.h'
@@ -0,0 +1,40 @@
+#ifndef LIBMATRIX_TEST_H_
+#define LIBMATRIX_TEST_H_
+
+class Options
+{
+ Options();
+ static const std::string verbose_name_;
+ static const std::string help_name_;
+ std::string app_name_;
+ bool show_help_;
+ bool verbose_;
+public:
+ Options(const std::string& app_name) :
+ app_name_(app_name),
+ show_help_(false),
+ verbose_(false) {}
+ ~Options() {}
+ bool beVerbose() const { return verbose_; }
+ bool showHelp() const { return show_help_; }
+ void parseArgs(int argc, char** argv);
+ void printUsage();
+};
+
+class MatrixTest
+{
+ std::string name_;
+protected:
+ bool pass_;
+ MatrixTest();
+public:
+ MatrixTest(const std::string& name) :
+ name_(name),
+ pass_(false) {}
+ ~MatrixTest();
+ const std::string& name() const { return name_; }
+ virtual void run(const Options& options) = 0;
+ const bool passed() const { return pass_; }
+};
+
+#endif // LIBMATRIX_TEST_H_
=== added file 'src/libmatrix/test/options.cc'
@@ -0,0 +1,56 @@
+#include <iostream>
+#include <iomanip>
+#include <getopt.h>
+#include "libmatrix_test.h"
+
+using std::cout;
+using std::endl;
+
+const std::string Options::verbose_name_("verbose");
+const std::string Options::help_name_("help");
+
+void
+Options::parseArgs(int argc, char** argv)
+{
+ static struct option long_options[] = {
+ {"verbose", 0, 0, 0},
+ {"help", 0, 0, 0},
+ {0, 0, 0, 0}
+ };
+ int option_index(0);
+ int c = getopt_long(argc, argv, "", long_options, &option_index);
+ while (c != -1)
+ {
+ std::string optname(long_options[option_index].name);
+
+ if (optname == verbose_name_)
+ {
+ verbose_ = true;
+ }
+ else if (optname == help_name_)
+ {
+ show_help_ = true;
+ }
+ c = getopt_long(argc, argv, "",
+ long_options, &option_index);
+ }
+}
+
+
+static void
+emitColumnOne(const std::string& text)
+{
+ cout << std::setw(16) << text;
+}
+
+void
+Options::printUsage()
+{
+ cout << app_name_ << ": directed functional test utility for libmatrix." << endl;
+ cout << "Options:" << endl;
+ emitColumnOne("--verbose");
+ cout << std::setw(0) << " Enable verbose output during test runs." << endl;
+ emitColumnOne("--help");
+ cout << std::setw(0) << " Print this usage text." << endl;
+}
+
=== modified file 'src/wscript_build'
@@ -1,11 +1,3 @@
-bld(
- features = ['cxx', 'cxxstlib'],
- source = bld.path.ant_glob('libmatrix/*.cc'),
- target = 'matrix',
- lib = ['m'],
- export_includes = 'libmatrix'
- )
-
def is_common(name):
return name.find('egl') == -1 and name.find('glx') == -1
@@ -14,6 +6,28 @@
glx_sources = ['composite-canvas-glx.cc', 'composite-window-glxpixmap.cc']
egl_sources = ['composite-canvas-egl.cc', 'composite-window-eglimage.cc']
+if bld.env.BUILD_EGL_GL or bld.env.BUILD_GLX:
+ bld(
+ features = ['cxx', 'cxxstlib'],
+ source = bld.path.ant_glob('libmatrix/*.cc'),
+ target = 'matrix',
+ lib = ['m'],
+ includes = ['.'],
+ defines = ['USE_GL'],
+ export_includes = 'libmatrix'
+ )
+
+if bld.env.BUILD_EGL_ES2:
+ bld(
+ features = ['cxx', 'cxxstlib'],
+ source = bld.path.ant_glob('libmatrix/*.cc'),
+ target = 'matrix-es2',
+ lib = ['m'],
+ includes = ['.'],
+ defines = ['USE_GLES2'],
+ export_includes = 'libmatrix'
+ )
+
if bld.env.BUILD_EGL_GL:
bld(
features = ['cxx', 'cprogram'],
@@ -31,7 +45,7 @@
source = common_sources + egl_sources,
target = 'glcompbench-egl-es2',
uselib = ['egl', 'glesv2', 'x11', 'xdamage', 'xcomposite'],
- use = ['matrix'],
+ use = ['matrix-es2'],
lib = ['m'],
defines = ['USE_EGL', 'USE_GLES2']
)