Edit

kc3-lang/angle/src/common/matrix_utils_unittest.cpp

Branch :

  • Show log

    Commit

  • Author : Cooper Partin
    Date : 2015-08-12 10:56:50
    Hash : 4d61f7ed
    Message : Reland Fixed compiler warning C4267 'conversion from 'size_t' to 'type', possible loss of data' Additional warnings found with more testing and added C4267 warning disable only for angle_libpng BUG=angleproject:1120 Change-Id: Ic403dcff5a8018056fa51a8c408e64207f3362eb Reviewed-on: https://chromium-review.googlesource.com/293028 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Geoff Lang <geofflang@chromium.org> Tested-by: Geoff Lang <geofflang@chromium.org>

  • src/common/matrix_utils_unittest.cpp
  • //
    // Copyright 2015 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // matrix_utils_unittests:
    //   Unit tests for the matrix utils.
    //
    
    #include "matrix_utils.h"
    
    #include <gtest/gtest.h>
    
    using namespace angle;
    
    namespace
    {
    
    const unsigned int minDimensions = 2;
    const unsigned int maxDimensions = 4;
    
    TEST(MatrixUtilsTest, MatrixConstructorTest)
    {
        for (unsigned int i = minDimensions; i <= maxDimensions; i++)
        {
            for (unsigned int j = minDimensions; j <= maxDimensions; j++)
            {
                unsigned int numElements = i * j;
                Matrix<float> m(std::vector<float>(numElements, 1.0f), i, j);
                EXPECT_EQ(m.rows(), i);
                EXPECT_EQ(m.columns(), j);
                EXPECT_EQ(m.elements(), std::vector<float>(numElements, 1.0f));
            }
        }
    
        for (unsigned int i = minDimensions; i <= maxDimensions; i++)
        {
            unsigned int numElements = i * i;
            Matrix<float> m(std::vector<float>(numElements, 1.0f), i);
            EXPECT_EQ(m.size(), i);
            EXPECT_EQ(m.columns(), m.columns());
            EXPECT_EQ(m.elements(), std::vector<float>(numElements, 1.0f));
        }
    }
    
    TEST(MatrixUtilsTest, MatrixCompMultTest)
    {
        for (unsigned int i = minDimensions; i <= maxDimensions; i++)
        {
            unsigned int numElements = i * i;
            Matrix<float> m1(std::vector<float>(numElements, 2.0f), i);
            Matrix<float> actualResult = m1.compMult(m1);
            std::vector<float> actualResultElements = actualResult.elements();
            std::vector<float> expectedResultElements(numElements, 4.0f);
            EXPECT_EQ(expectedResultElements, actualResultElements);
        }
    }
    
    TEST(MatrixUtilsTest, MatrixOuterProductTest)
    {
        for (unsigned int i = minDimensions; i <= maxDimensions; i++)
        {
            for (unsigned int j = minDimensions; j <= maxDimensions; j++)
            {
                unsigned int numElements = i * j;
                Matrix<float> m1(std::vector<float>(numElements, 2.0f), i, 1);
                Matrix<float> m2(std::vector<float>(numElements, 2.0f), 1, j);
                Matrix<float> actualResult = m1.outerProduct(m2);
                EXPECT_EQ(actualResult.rows(), i);
                EXPECT_EQ(actualResult.columns(), j);
                std::vector<float> actualResultElements = actualResult.elements();
                std::vector<float> expectedResultElements(numElements, 4.0f);
                EXPECT_EQ(expectedResultElements, actualResultElements);
            }
        }
    }
    
    TEST(MatrixUtilsTest, MatrixTransposeTest)
    {
        for (unsigned int i = minDimensions; i <= maxDimensions; i++)
        {
            for (unsigned int j = minDimensions; j <= maxDimensions; j++)
            {
                unsigned int numElements = i * j;
                Matrix<float> m1(std::vector<float>(numElements, 2.0f), i, j);
                Matrix<float> expectedResult = Matrix<float>(std::vector<float>(numElements, 2.0f), j, i);
                Matrix<float> actualResult = m1.transpose();
                EXPECT_EQ(expectedResult.elements(), actualResult.elements());
                EXPECT_EQ(actualResult.rows(), expectedResult.rows());
                EXPECT_EQ(actualResult.columns(), expectedResult.columns());
                // transpose(transpose(A)) = A
                Matrix<float> m2 = actualResult.transpose();
                EXPECT_EQ(m1.elements(), m2.elements());
            }
        }
    }
    
    TEST(MatrixUtilsTest, MatrixDeterminantTest)
    {
        for (unsigned int i = minDimensions; i <= maxDimensions; i++)
        {
            unsigned int numElements = i * i;
            Matrix<float> m(std::vector<float>(numElements, 2.0f), i);
            EXPECT_EQ(m.determinant(), 0.0f);
        }
    }
    
    TEST(MatrixUtilsTest, 2x2MatrixInverseTest)
    {
        float inputElements[] =
        {
            2.0f, 5.0f,
            3.0f, 7.0f
        };
        unsigned int numElements = 4;
        std::vector<float> input(inputElements, inputElements + numElements);
        Matrix<float> inputMatrix(input, 2);
        float identityElements[] =
        {
            1.0f, 0.0f,
            0.0f, 1.0f
        };
        std::vector<float> identityMatrix(identityElements, identityElements + numElements);
        // A * inverse(A) = I, where I is identity matrix.
        Matrix<float> result = inputMatrix * inputMatrix.inverse();
        EXPECT_EQ(identityMatrix, result.elements());
    }
    
    TEST(MatrixUtilsTest, 3x3MatrixInverseTest)
    {
        float inputElements[] =
        {
            11.0f, 23.0f, 37.0f,
            13.0f, 29.0f, 41.0f,
            19.0f, 31.0f, 43.0f
        };
        unsigned int numElements = 9;
        std::vector<float> input(inputElements, inputElements + numElements);
        Matrix<float> inputMatrix(input, 3);
        float identityElements[] =
        {
            1.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f
        };
        std::vector<float> identityMatrix(identityElements, identityElements + numElements);
        // A * inverse(A) = I, where I is identity matrix.
        Matrix<float> result = inputMatrix * inputMatrix.inverse();
        std::vector<float> resultElements = result.elements();
        const float floatFaultTolarance = 0.000001f;
        for (size_t i = 0; i < numElements; i++)
            EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance);
    }
    
    TEST(MatrixUtilsTest, 4x4MatrixInverseTest)
    {
        float inputElements[] =
        {
            29.0f, 43.0f, 61.0f, 79.0f,
            31.0f, 47.0f, 67.0f, 83.0f,
            37.0f, 53.0f, 71.0f, 89.0f,
            41.0f, 59.0f, 73.0f, 97.0f
        };
        unsigned int numElements = 16;
        std::vector<float> input(inputElements, inputElements + numElements);
        Matrix<float> inputMatrix(input, 4);
        float identityElements[] =
        {
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, 1.0f,
        };
        std::vector<float> identityMatrix(identityElements, identityElements + numElements);
        // A * inverse(A) = I, where I is identity matrix.
        Matrix<float> result = inputMatrix * inputMatrix.inverse();
        std::vector<float> resultElements = result.elements();
        const float floatFaultTolarance = 0.00001f;
        for (unsigned int i = 0; i < numElements; i++)
            EXPECT_NEAR(resultElements[i], identityMatrix[i], floatFaultTolarance);
    }
    
    }