From 01b37778be57454c90eb8356f97f438898def43a Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 29 Jan 2014 14:53:16 -0500 Subject: [PATCH 01/30] Update readme to reflect command line tool changes --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index bdecfb0..66e7d55 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,9 @@ compression time and PSNR. * [DXT1](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2] * [DXT5](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2] * [PVRTC](http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf) +* `-d`: Specifies the decompressed output file. + * **Default**: -.png +* `-nd`: Suppress decompressed output. * `-t`: Specifies the number of threads to use for compression. * **Default**: 1 * **Formats**: BPTC, ETC1, DXT1, DXT5 From 426d12e5c9625d337e61eb71fefc388e97f09024 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 29 Jan 2014 14:54:14 -0500 Subject: [PATCH 02/30] Fix formatting --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66e7d55..adf612b 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ compression time and PSNR. * [DXT5](http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt) [2] * [PVRTC](http://web.onetel.net.uk/~simonnihal/assorted3d/fenney03texcomp.pdf) * `-d`: Specifies the decompressed output file. - * **Default**: -.png + * **Default**: ``-``.png * `-nd`: Suppress decompressed output. * `-t`: Specifies the number of threads to use for compression. * **Default**: 1 From 37ffc102d00c52ddcdd1babbcb9e0017aa3e6816 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 30 Jan 2014 13:34:52 -0500 Subject: [PATCH 03/30] Add shuffle operator to pixels. --- Base/include/Pixel.h | 11 +++++++++++ Base/src/Pixel.cpp | 23 +++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/Base/include/Pixel.h b/Base/include/Pixel.h index 54555c9..1f6afe2 100644 --- a/Base/include/Pixel.h +++ b/Base/include/Pixel.h @@ -143,6 +143,17 @@ class Pixel : public Vector4 { uint32 Pack() const; void Unpack(uint32 rgba); + // Shuffles the pixel values around so that they change their ordering based + // on the passed mask. The values are chosen such that each two bits from the + // least significant bit define a value from 0-3. From LSB to MSB, the values + // are labelled a, b, c, d. From these labels, we store: + // m_Pixels[0] = m_Pixels[a] + // m_Pixels[1] = m_Pixels[b] + // m_Pixels[2] = m_Pixels[c] + // m_Pixels[3] = m_Pixels[d] + // hence, 0xE4 (11 10 01 00) represents a no-op. + void Shuffle(uint8 shuffleMask = 0xE4); + // Tests for equality by comparing the values and the bit depths. bool operator==(const Pixel &) const; }; diff --git a/Base/src/Pixel.cpp b/Base/src/Pixel.cpp index 01582ef..8364dd2 100644 --- a/Base/src/Pixel.cpp +++ b/Base/src/Pixel.cpp @@ -222,6 +222,29 @@ namespace FasTC { B() = ChangeBitDepth((rgba >> 16) & 0xFF, 8, m_BitDepth[3]); } + void Pixel::Shuffle(uint8 shuffleMask) { + Pixel thisPixel(*this); + uint8 a = shuffleMask & 3; + uint8 b = (shuffleMask >> 2) & 3; + uint8 c = (shuffleMask >> 4) & 3; + uint8 d = (shuffleMask >> 6) & 3; + + Pixel tmp; + tmp[0] = thisPixel[a]; + tmp.m_BitDepth[0] = thisPixel.m_BitDepth[a]; + + tmp[1] = thisPixel[b]; + tmp.m_BitDepth[1] = thisPixel.m_BitDepth[b]; + + tmp[2] = thisPixel[c]; + tmp.m_BitDepth[2] = thisPixel.m_BitDepth[c]; + + tmp[3] = thisPixel[d]; + tmp.m_BitDepth[3] = thisPixel.m_BitDepth[d]; + + *this = tmp; + } + bool Pixel::operator==(const Pixel &other) const { uint8 depths[4]; other.GetBitDepth(depths); From 1a5b748b2caa7e749574ad84b234f0c6c4900857 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 30 Jan 2014 13:55:55 -0500 Subject: [PATCH 04/30] Check for C++11 types in base library --- BPTCEncoder/CMakeLists.txt | 1 + Base/CMakeLists.txt | 24 ++++++++++ Base/config/FasTCBaseConfig.h.in | 54 +++++++++++++++++++++++ Base/include/TexCompTypes.h | 75 +++++++++++++++++++++++--------- Base/test/CMakeLists.txt | 4 +- CLTool/CMakeLists.txt | 2 + Core/CMakeLists.txt | 4 +- DXTEncoder/CMakeLists.txt | 1 + ETCEncoder/CMakeLists.txt | 1 + IO/CMakeLists.txt | 9 ++-- PVRTCEncoder/CMakeLists.txt | 1 + PVRTCEncoder/test/CMakeLists.txt | 4 +- 12 files changed, 153 insertions(+), 27 deletions(-) create mode 100644 Base/config/FasTCBaseConfig.h.in diff --git a/BPTCEncoder/CMakeLists.txt b/BPTCEncoder/CMakeLists.txt index 6b1b125..145cf4c 100644 --- a/BPTCEncoder/CMakeLists.txt +++ b/BPTCEncoder/CMakeLists.txt @@ -41,6 +41,7 @@ # INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/BPTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/BPTCEncoder/include) diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt index 15d1044..4dfdc82 100644 --- a/Base/CMakeLists.txt +++ b/Base/CMakeLists.txt @@ -49,6 +49,28 @@ # # +INCLUDE(CheckCXXSourceCompiles) +CHECK_CXX_SOURCE_COMPILES(" + #include + int main() { + int8_t x8 = 0; + int16_t x16 = 1; + int32_t x32 = 2; + int64_t x64 = 3; + uint8_t ux8 = 0; + uint16_t ux16 = 1; + uint32_t ux32 = 2; + uint64_t ux64 = 3; + return (x8 | ux8 | x16 | ux16 | x32 | ux32 | x64 | ux64); + }" + HAS_CPP11_TYPES +) + +CONFIGURE_FILE( + "config/FasTCBaseConfig.h.in" + "include/FasTCBaseConfig.h" +) + SET( SOURCES "src/Image.cpp" "src/CompressionJob.cpp" @@ -60,6 +82,7 @@ SET( SOURCES SET( HEADERS "include/Color.h" "include/CompressionJob.h" + "config/FasTCBaseConfig.h.in" "include/IPixel.h" "include/Image.h" "include/MatrixBase.h" @@ -75,6 +98,7 @@ SET( HEADERS ) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) ADD_LIBRARY( FasTCBase ${HEADERS} diff --git a/Base/config/FasTCBaseConfig.h.in b/Base/config/FasTCBaseConfig.h.in new file mode 100644 index 0000000..b39ac46 --- /dev/null +++ b/Base/config/FasTCBaseConfig.h.in @@ -0,0 +1,54 @@ +/* FasTC + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. + * + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . + * + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. + * + * Please send all BUG REPORTS to . + * + * The authors may be contacted via: + * + * Pavel Krajcevski + * Dept of Computer Science + * 201 S Columbia St + * Frederick P. Brooks, Jr. Computer Science Bldg + * Chapel Hill, NC 27599-3175 + * USA + * + * + */ + +// Does our compiler support cpp11 types? +#cmakedefine FASTC_BASE_HAS_CPP11_TYPES diff --git a/Base/include/TexCompTypes.h b/Base/include/TexCompTypes.h index 5290b41..dfbcd9b 100644 --- a/Base/include/TexCompTypes.h +++ b/Base/include/TexCompTypes.h @@ -1,30 +1,39 @@ /* FasTC - * Copyright (c) 2012 University of North Carolina at Chapel Hill. All rights reserved. + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. * - * Permission to use, copy, modify, and distribute this software and its documentation for educational, - * research, and non-profit purposes, without fee, and without a written agreement is hereby granted, - * provided that the above copyright notice, this paragraph, and the following four paragraphs appear - * in all copies. + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. * - * Permission to incorporate this software into commercial products may be obtained by contacting the - * authors or the Office of Technology Development at the University of North Carolina at Chapel Hill . + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . * - * This software program and documentation are copyrighted by the University of North Carolina at Chapel Hill. - * The software program and documentation are supplied "as is," without any accompanying services from the - * University of North Carolina at Chapel Hill or the authors. The University of North Carolina at Chapel Hill - * and the authors do not warrant that the operation of the program will be uninterrupted or error-free. The - * end-user understands that the program was developed for research purposes and is advised not to rely - * exclusively on the program for any reason. + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. * - * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE - * USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE - * AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. * - * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY - * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY - * OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS. * * Please send all BUG REPORTS to . @@ -48,6 +57,28 @@ #ifndef _TEX_COMP_TYPES_H_ #define _TEX_COMP_TYPES_H_ +#include "FasTCBaseConfig.h" + +// Do we support C++11? +#ifdef FASTC_BASE_HAS_CPP11_TYPES +#include + +typedef int8_t int8; +typedef uint8_t uint8; + +typedef int16_t int16; +typedef uint16_t uint16; + +typedef int32_t int32; +typedef uint32_t uint32; + +typedef int64_t int64; +typedef uint64_t uint64; + +typedef int8_t CHAR; + +#else + // Windows? #ifdef _MSC_VER @@ -83,4 +114,6 @@ typedef char CHAR; #endif // _MSC_VER +#endif // FASTC_BASE_HAS_CPP11_TYPES + #endif // _TEX_COMP_TYPES_H_ diff --git a/Base/test/CMakeLists.txt b/Base/test/CMakeLists.txt index ff349c8..1ceaf56 100644 --- a/Base/test/CMakeLists.txt +++ b/Base/test/CMakeLists.txt @@ -49,7 +49,9 @@ # # -INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include ) + INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS diff --git a/CLTool/CMakeLists.txt b/CLTool/CMakeLists.txt index 2205688..73de05b 100644 --- a/CLTool/CMakeLists.txt +++ b/CLTool/CMakeLists.txt @@ -41,6 +41,8 @@ # INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/Base/include ) + INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Core/include ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/include ) diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index 78430b0..3af98a6 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -49,6 +49,9 @@ # # +INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/Base/include ) + SET( SOURCES "src/TexComp.cpp" "src/CompressedImage.cpp" @@ -74,7 +77,6 @@ ELSE() SET( LINK_FLAGS -lrt ${LINK_FLAGS} ) ENDIF() -INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR} ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/ETCEncoder/include ) diff --git a/DXTEncoder/CMakeLists.txt b/DXTEncoder/CMakeLists.txt index 9774136..015bd96 100755 --- a/DXTEncoder/CMakeLists.txt +++ b/DXTEncoder/CMakeLists.txt @@ -41,6 +41,7 @@ # INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/DXTEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/DXTEncoder/include) diff --git a/ETCEncoder/CMakeLists.txt b/ETCEncoder/CMakeLists.txt index a05bd4b..f23bc82 100644 --- a/ETCEncoder/CMakeLists.txt +++ b/ETCEncoder/CMakeLists.txt @@ -41,6 +41,7 @@ # INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/ETCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/ETCEncoder/include) diff --git a/IO/CMakeLists.txt b/IO/CMakeLists.txt index dc90d3c..272e624 100644 --- a/IO/CMakeLists.txt +++ b/IO/CMakeLists.txt @@ -40,6 +40,12 @@ # # +INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/Base/include) + +INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/IO/include ) +INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/include ) + SET( SOURCES "src/ImageWriter.cpp" "src/ImageLoader.cpp" @@ -108,9 +114,6 @@ CONFIGURE_FILE( "include/ImageWriter.h" ) -INCLUDE_DIRECTORIES( ${FasTC_BINARY_DIR}/IO/include ) -INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/IO/include ) -INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Base/include ) INCLUDE_DIRECTORIES( ${FasTC_SOURCE_DIR}/Core/include ) ADD_LIBRARY(FasTCIO diff --git a/PVRTCEncoder/CMakeLists.txt b/PVRTCEncoder/CMakeLists.txt index 2f8845b..555c1dd 100644 --- a/PVRTCEncoder/CMakeLists.txt +++ b/PVRTCEncoder/CMakeLists.txt @@ -53,6 +53,7 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include) SET( HEADERS include/PVRTCCompressor.h diff --git a/PVRTCEncoder/test/CMakeLists.txt b/PVRTCEncoder/test/CMakeLists.txt index 57de2e6..a399ee8 100644 --- a/PVRTCEncoder/test/CMakeLists.txt +++ b/PVRTCEncoder/test/CMakeLists.txt @@ -53,7 +53,9 @@ INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/PVRTCEncoder/include) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/PVRTCEncoder/src) -INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include) +INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/Base/include ) +INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include ) + INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS From b61c6965294dad0d5a9a5946683a45d157e82bb3 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 30 Jan 2014 14:09:44 -0500 Subject: [PATCH 05/30] Some small bugs --- Base/CMakeLists.txt | 2 +- Base/include/TexCompTypes.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt index 4dfdc82..68eae2a 100644 --- a/Base/CMakeLists.txt +++ b/Base/CMakeLists.txt @@ -63,7 +63,7 @@ CHECK_CXX_SOURCE_COMPILES(" uint64_t ux64 = 3; return (x8 | ux8 | x16 | ux16 | x32 | ux32 | x64 | ux64); }" - HAS_CPP11_TYPES + FASTC_BASE_HAS_CPP11_TYPES ) CONFIGURE_FILE( diff --git a/Base/include/TexCompTypes.h b/Base/include/TexCompTypes.h index dfbcd9b..779c91b 100644 --- a/Base/include/TexCompTypes.h +++ b/Base/include/TexCompTypes.h @@ -75,7 +75,7 @@ typedef uint32_t uint32; typedef int64_t int64; typedef uint64_t uint64; -typedef int8_t CHAR; +typedef char CHAR; #else From f32a943a909432c5c2021b1b47022e226ce2b50b Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 30 Jan 2014 14:09:44 -0500 Subject: [PATCH 06/30] Some small bugs, fixed #2 --- Base/CMakeLists.txt | 2 +- Base/include/TexCompTypes.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Base/CMakeLists.txt b/Base/CMakeLists.txt index 4dfdc82..68eae2a 100644 --- a/Base/CMakeLists.txt +++ b/Base/CMakeLists.txt @@ -63,7 +63,7 @@ CHECK_CXX_SOURCE_COMPILES(" uint64_t ux64 = 3; return (x8 | ux8 | x16 | ux16 | x32 | ux32 | x64 | ux64); }" - HAS_CPP11_TYPES + FASTC_BASE_HAS_CPP11_TYPES ) CONFIGURE_FILE( diff --git a/Base/include/TexCompTypes.h b/Base/include/TexCompTypes.h index dfbcd9b..779c91b 100644 --- a/Base/include/TexCompTypes.h +++ b/Base/include/TexCompTypes.h @@ -75,7 +75,7 @@ typedef uint32_t uint32; typedef int64_t int64; typedef uint64_t uint64; -typedef int8_t CHAR; +typedef char CHAR; #else From a530ae937e3f50c1b4b99c5ffeff01a882cb1528 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Tue, 4 Feb 2014 12:55:47 -0500 Subject: [PATCH 07/30] Fix a few bugs. --- Base/include/Image.h | 4 ++-- ETCEncoder/src/Decompressor.cpp | 4 ++-- IO/src/ImageLoaderKTX.cpp | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Base/include/Image.h b/Base/include/Image.h index f7b97fc..1cddb8b 100644 --- a/Base/include/Image.h +++ b/Base/include/Image.h @@ -87,8 +87,8 @@ namespace FasTC { template void ConvertTo(Image &other) const { - for(uint32 j = 0; j < other.GetWidth(); j++) { - for(uint32 i = 0; i < other.GetHeight(); i++) { + for(uint32 j = 0; j < other.GetHeight(); j++) { + for(uint32 i = 0; i < other.GetWidth(); i++) { other(i, j).Unpack((*this)(i, j).Pack()); } } diff --git a/ETCEncoder/src/Decompressor.cpp b/ETCEncoder/src/Decompressor.cpp index f99fede..92c8b93 100644 --- a/ETCEncoder/src/Decompressor.cpp +++ b/ETCEncoder/src/Decompressor.cpp @@ -60,8 +60,8 @@ namespace ETCC { uint32 blocksX = cj.Width() / 4; uint32 blocksY = cj.Height() / 4; - for(uint32 j = 0; j < blocksX; j++) { - for(uint32 i = 0; i < blocksY; i++) { + for(uint32 j = 0; j < blocksY; j++) { + for(uint32 i = 0; i < blocksX; i++) { uint32 pixels[16]; uint32 blockIdx = j*blocksX + i; rg_etc1::unpack_etc1_block(cj.InBuf() + blockIdx * 8, pixels); diff --git a/IO/src/ImageLoaderKTX.cpp b/IO/src/ImageLoaderKTX.cpp index 55de436..d1f1bd0 100644 --- a/IO/src/ImageLoaderKTX.cpp +++ b/IO/src/ImageLoaderKTX.cpp @@ -103,6 +103,7 @@ class IntLoader { class BigEndianIntLoader : public IntLoader { public: + BigEndianIntLoader() { } virtual uint32 ReadInt(const uint8 *data) const { uint32 ret = 0; ret |= data[0]; @@ -117,10 +118,11 @@ static const BigEndianIntLoader gBEldr; class LittleEndianIntLoader : public IntLoader { public: + LittleEndianIntLoader() { } virtual uint32 ReadInt(const uint8 *data) const { uint32 ret = 0; ret |= data[3]; - for(uint32 i = 3; i >= 0; i--) { + for(int32 i = 3; i >= 0; i--) { ret <<= 8; ret |= data[i]; } From e20d84b1eea93d40afe58b7756f50ba072347b4b Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 12:30:09 -0500 Subject: [PATCH 08/30] Fix gross bug in VectorBase --- Base/include/VectorBase.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index dc78d01..55cc707 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -170,8 +170,8 @@ namespace FasTC { VectorSwitch(const TypeOne &a, const TypeTwo &b) : m_A(a), m_B(b) { } - const TypeOne &GetVector() { return m_A; } - const TypeTwo &GetScalar() { return m_B; } + const VectorType &GetVector() { return m_A; } + const ScalarType &GetScalar() { return m_B; } }; template @@ -187,8 +187,8 @@ namespace FasTC { VectorSwitch(const TypeOne &a, const TypeTwo &b) : m_A(a), m_B(b) { } - const TypeOne &GetVector() { return m_B; } - const TypeTwo &GetScalar() { return m_A; } + const VectorType &GetVector() { return m_B; } + const ScalarType &GetScalar() { return m_A; } }; template From 543185fe2a1cb0bfdbbc88c92c5ceba0fb78cfec Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 12:30:37 -0500 Subject: [PATCH 09/30] Add normalization function to vectors --- Base/include/VectorBase.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index 55cc707..3aa2232 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -85,6 +85,13 @@ namespace FasTC { T LengthSq() const { return this->Dot(*this); } T Length() const { return sqrt(LengthSq()); } + + void Normalize() { + T len = Length(); + for(int i = 0; i < N; i++) { + vec[i] /= len; + } + } }; // Operators From 9f0603aaa82e9355ae7fe3ead99ae3b002842a67 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 12:33:05 -0500 Subject: [PATCH 10/30] Add scaling tests to make sure that bit depths are preserved. --- Base/test/TestPixel.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Base/test/TestPixel.cpp b/Base/test/TestPixel.cpp index 0a630b8..9d95fd9 100644 --- a/Base/test/TestPixel.cpp +++ b/Base/test/TestPixel.cpp @@ -248,3 +248,33 @@ TEST(Pixel, UnpackRGBA) { EXPECT_EQ(p.G(), 0x3); EXPECT_EQ(p.R(), 0x1f); } + +TEST(Pixel, ScaleColor) { + FasTC::Pixel p; + uint8 newBitDepth[4] = { 3, 5, 2, 1 }; // A R G B + p.ChangeBitDepth(newBitDepth); + + p.R() = 1; + p.G() = 2; + p.B() = 3; + p.A() = 4; + + FasTC::Pixel sp = p * 3; + FasTC::Pixel ps = 3 * p; + + EXPECT_EQ(sp.R(), 3); EXPECT_EQ(ps.R(), 3); + EXPECT_EQ(sp.G(), 6); EXPECT_EQ(ps.G(), 6); + EXPECT_EQ(sp.B(), 9); EXPECT_EQ(ps.B(), 9); + EXPECT_EQ(sp.A(), 12); EXPECT_EQ(ps.A(), 12); + + uint8 bd[4]; + sp.GetBitDepth(bd); + for(uint32 i = 0; i < 4; i++) { + EXPECT_EQ(bd[i], newBitDepth[i]); + } + + ps.GetBitDepth(bd); + for(uint32 i = 0; i < 4; i++) { + EXPECT_EQ(bd[i], newBitDepth[i]); + } +} From 92f5893650de843e8bd1053692d76fea497fa370 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 13:20:43 -0500 Subject: [PATCH 11/30] Add first vector tests --- Base/test/CMakeLists.txt | 14 +++++++- Base/test/TestVector.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 Base/test/TestVector.cpp diff --git a/Base/test/CMakeLists.txt b/Base/test/CMakeLists.txt index 1ceaf56..8295630 100644 --- a/Base/test/CMakeLists.txt +++ b/Base/test/CMakeLists.txt @@ -55,7 +55,7 @@ INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include ) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS - Pixel Image Color + Vector Pixel Image Color ) FOREACH(TEST ${TESTS}) @@ -68,6 +68,18 @@ FOREACH(TEST ${TESTS}) ENDIF() ADD_EXECUTABLE(${TEST_NAME} ${TEST_MODULE}) + + # Vector tests need to use uninitialized variables + IF(${TEST_NAME} STREQUAL "Test_Base_Vector") + IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) + SET_TARGET_PROPERTIES( + ${TEST_NAME} + PROPERTIES + COMPILE_FLAGS + "-Wno-uninitialized") + ENDIF() + ENDIF() + TARGET_LINK_LIBRARIES(${TEST_NAME} FasTCBase) TARGET_LINK_LIBRARIES(${TEST_NAME} gtest_main) ADD_TEST(${TEST_NAME} ${TEST_NAME}) diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp new file mode 100644 index 0000000..9abd2e6 --- /dev/null +++ b/Base/test/TestVector.cpp @@ -0,0 +1,75 @@ +/* FasTC + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. + * + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . + * + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. + * + * Please send all BUG REPORTS to . + * + * The authors may be contacted via: + * + * Pavel Krajcevski + * Dept of Computer Science + * 201 S Columbia St + * Frederick P. Brooks, Jr. Computer Science Bldg + * Chapel Hill, NC 27599-3175 + * USA + * + * + */ + +#include "gtest/gtest.h" +#include "TexCompTypes.h" +#include "VectorBase.h" + +TEST(VectorBase, Constructors) { + FasTC::VectorBase v3f; + FasTC::VectorBase v1d; + FasTC::VectorBase v7i; + FasTC::VectorBase v16u; + +#define TEST_VECTOR_COPY_CONS(v, t, n) \ + do { \ + FasTC::VectorBase d##v (v); \ + for(uint32 i = 0; i < n; i++) { \ + EXPECT_EQ(d##v [i], v[i]); \ + } \ + } while(0) \ + + TEST_VECTOR_COPY_CONS(v3f, float, 3); + TEST_VECTOR_COPY_CONS(v1d, double, 1); + TEST_VECTOR_COPY_CONS(v7i, int, 7); + TEST_VECTOR_COPY_CONS(v16u, uint32, 16); +} From 45b739a44aad28f1d7e4064134a6ea7d99f89bc5 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 17:17:25 -0500 Subject: [PATCH 12/30] Add some tests for VectorBase --- Base/include/VectorBase.h | 8 +- Base/test/TestVector.cpp | 150 +++++++++++++++++++++++++++++++++++++- 2 files changed, 152 insertions(+), 6 deletions(-) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index 3aa2232..50f9ef1 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -61,7 +61,7 @@ namespace FasTC { const T &operator[](int idx) const { return vec[idx]; } // Allow casts to the respective array representation... - operator T *() const { return vec; } + operator const T *() const { return vec; } VectorBase &operator=(const T *v) { for(int i = 0; i < N; i++) vec[i] = v[i]; @@ -71,7 +71,11 @@ namespace FasTC { // Allows casting to other vector types if the underlying type system does as well... template operator VectorBase<_T, N>() const { - return VectorBase<_T, N>(vec); + VectorBase<_T, N> ret; + for(int i = 0; i < N; i++) { + ret[i] = static_cast<_T>(vec[i]); + } + return ret; } // Vector operations diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp index 9abd2e6..45c05a4 100644 --- a/Base/test/TestVector.cpp +++ b/Base/test/TestVector.cpp @@ -51,19 +51,20 @@ */ #include "gtest/gtest.h" -#include "TexCompTypes.h" #include "VectorBase.h" +static const float kEpsilon = 1e-6; + TEST(VectorBase, Constructors) { FasTC::VectorBase v3f; FasTC::VectorBase v1d; FasTC::VectorBase v7i; - FasTC::VectorBase v16u; + FasTC::VectorBase v16u; #define TEST_VECTOR_COPY_CONS(v, t, n) \ do { \ FasTC::VectorBase d##v (v); \ - for(uint32 i = 0; i < n; i++) { \ + for(int i = 0; i < n; i++) { \ EXPECT_EQ(d##v [i], v[i]); \ } \ } while(0) \ @@ -71,5 +72,146 @@ TEST(VectorBase, Constructors) { TEST_VECTOR_COPY_CONS(v3f, float, 3); TEST_VECTOR_COPY_CONS(v1d, double, 1); TEST_VECTOR_COPY_CONS(v7i, int, 7); - TEST_VECTOR_COPY_CONS(v16u, uint32, 16); + TEST_VECTOR_COPY_CONS(v16u, unsigned, 16); + +#undef TEST_VECTOR_COPY_CONS +} + +TEST(VectorBase, Accessors) { + FasTC::VectorBase v3f; + v3f[0] = 1.0f; + v3f[1] = -2.3f; + v3f[2] = 1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], v3f(i)); + } + + v3f(0) = -1.0f; + v3f(1) = 2.3f; + v3f(2) = -1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f(i), v3f[i]); + } +} + +TEST(VectorBase, PointerConversion) { + FasTC::VectorBase v3f; + v3f[0] = 1.0f; + v3f[1] = -2.3f; + v3f[2] = 1000; + + float cmp[3] = { 1.0f, -2.3f, 1000 }; + const float *v3fp = v3f; + int result = memcmp(cmp, v3fp, 3 * sizeof(float)); + EXPECT_EQ(result, 0); + + cmp[0] = -1.0f; + cmp[1] = 2.3f; + cmp[2] = 1000.0f; + v3f = cmp; + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], cmp[i]); + } +} + +TEST(VectorBase, CastVector) { + FasTC::VectorBase v3f; + FasTC::VectorBase v3d = v3f; + FasTC::VectorBase v3i = v3f; + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3d(i), static_cast(v3f(i))); + EXPECT_EQ(v3i(i), static_cast(v3f(i))); + } +} + +TEST(VectorBase, DotProduct) { + int iv[5] = { -2, -1, 0, 1, 2 }; + FasTC::VectorBase v5i(iv); + + unsigned uv[5] = { 1, 2, 3, 4, 5 }; + FasTC::VectorBase v5u(uv); + + EXPECT_EQ(v5i.Dot(v5u), 10); + EXPECT_EQ(v5u.Dot(v5i), 10); +} + +TEST(VectorBase, Length) { + int iv[5] = { 1, 2, 3, 4, 5 }; + FasTC::VectorBase v5i (iv); + + EXPECT_EQ(v5i.LengthSq(), 55); + EXPECT_EQ(v5i.Length(), 7); + + float fv[6] = {1, 2, 3, 4, 5, 6}; + FasTC::VectorBase v6f (fv); + + EXPECT_EQ(v6f.LengthSq(), 91); + EXPECT_NEAR(v6f.Length(), sqrt(91.0f), kEpsilon); +} + +TEST(VectorBase, Normalization) { + float fv[2] = {1, 0}; + FasTC::VectorBase v2f (fv); + v2f.Normalize(); + EXPECT_EQ(v2f[0], 1); + EXPECT_EQ(v2f[1], 0); + + // Normalized vector should be sqrt(2) for each axis, although + // this can't be represented as integers... + unsigned uv[2] = {2, 2}; + FasTC::VectorBase v2u (uv); + v2u.Normalize(); + EXPECT_EQ(v2u[0], 1); + EXPECT_EQ(v2u[1], 1); + + const float sqrt2 = sqrt(2)/2.0f; + for(int i = 2; i < 10; i++) { + v2f[0] = static_cast(i); + v2f[1] = static_cast(i); + v2f.Normalize(); + EXPECT_NEAR(v2f[0], sqrt2, kEpsilon); + EXPECT_NEAR(v2f[1], sqrt2, kEpsilon); + } +} + +TEST(VectorBase, Scaling) { + float fv[2] = {1.0f, 3.0f}; + FasTC::VectorBase v2f (fv); + FasTC::VectorBase v2fd = v2f * 3.0f; + EXPECT_NEAR(v2fd[0], 3.0f, kEpsilon); + EXPECT_NEAR(v2fd[1], 9.0f, kEpsilon); + + v2fd = -1.0 * v2f; + EXPECT_NEAR(v2fd[0], -1.0f, kEpsilon); + EXPECT_NEAR(v2fd[1], -3.0f, kEpsilon); + + v2fd = v2f / 3; + EXPECT_NEAR(v2fd[0], 1.0f / 3.0f, kEpsilon); + EXPECT_NEAR(v2fd[1], 1.0f, kEpsilon); +} + +TEST(VectorBase, Addition) { + float fv[2] = {1.1f, 3.2f}; + FasTC::VectorBase v2f (fv); + + unsigned uv[2] = {5, 2}; + FasTC::VectorBase v2u (uv); + + FasTC::VectorBase au = v2u + v2f; + EXPECT_EQ(au[0], 6); + EXPECT_EQ(au[1], 5); + + FasTC::VectorBase af = v2f + v2u; + EXPECT_NEAR(af[0], 6.1f, kEpsilon); + EXPECT_NEAR(af[1], 5.2f, kEpsilon); + + au = v2u - v2f; + EXPECT_EQ(au[0], 3); + EXPECT_EQ(au[1], 0); + + af = v2f - v2u; + EXPECT_NEAR(af[0], -3.9f, kEpsilon); + EXPECT_NEAR(af[1], 1.2f, kEpsilon); } From 2213e1b7d61404af0a0aa1a3da67e449f6947577 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 18:28:37 -0500 Subject: [PATCH 13/30] Add tests for special vector cases --- Base/include/Vector2.h | 14 ++- Base/include/Vector3.h | 16 +++- Base/include/Vector4.h | 16 +++- Base/test/TestVector.cpp | 201 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 235 insertions(+), 12 deletions(-) diff --git a/Base/include/Vector2.h b/Base/include/Vector2.h index 52bce4b..09f4be3 100644 --- a/Base/include/Vector2.h +++ b/Base/include/Vector2.h @@ -27,10 +27,8 @@ #include "VectorBase.h" -#ifdef _VEX_ENABLE_SWIZZLE_ # define _VEX_VEC2_SWIZZLE_DEF(X, Y) \ Vector2 X##Y() const { return Vector2( X(), Y() ); } -#endif // _VEX_ENABLE_SWIZZLE_ namespace FasTC { @@ -46,6 +44,11 @@ namespace FasTC { Y() = y; } + explicit Vector2(const T *_vec) { + for(int i = 0; i < 2; i++) + this->vec[i] = _vec[i]; + } + // Overloaded functions template Vector2(const Vector2<_T> &v) : VectorBase(v) { } @@ -56,6 +59,11 @@ namespace FasTC { return *this; } + Vector2 &operator=(const T *_vec) { + VectorBase::operator=(_vec); + return *this; + } + // Accessors T &X() { return (*this)[0]; } const T &X() const { return (*this)[0]; } @@ -64,12 +72,10 @@ namespace FasTC { const T &Y() const { return (*this)[1]; } // Swizzle - #ifdef _VEX_ENABLE_SWIZZLE_ _VEX_VEC2_SWIZZLE_DEF(X, X) _VEX_VEC2_SWIZZLE_DEF(X, Y) _VEX_VEC2_SWIZZLE_DEF(Y, X) _VEX_VEC2_SWIZZLE_DEF(Y, Y) - #endif //_VEX_ENABLE_SWIZZLE_ }; REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector2); diff --git a/Base/include/Vector3.h b/Base/include/Vector3.h index 02de606..2b6f950 100644 --- a/Base/include/Vector3.h +++ b/Base/include/Vector3.h @@ -27,10 +27,8 @@ #include "Vector2.h" -#ifdef _VEX_ENABLE_SWIZZLE_ # define _VEX_VEC3_SWIZZLE_DEF(X, Y, Z) \ Vector3 X##Y##Z() const { return Vector3( X(), Y(), Z() ); } -#endif // _VEX_ENABLE_SWIZZLE_ namespace FasTC { @@ -43,6 +41,12 @@ namespace FasTC { Y() = y; Z() = z; } + + explicit Vector3(const T *_vec) { + for(int i = 0; i < 3; i++) { + this->vec[i] = _vec[i]; + } + } // Overloaded functions template @@ -54,6 +58,12 @@ namespace FasTC { return *this; } + template + Vector3 &operator=(const _T *v) { + VectorBase::operator=(v); + return *this; + } + // Accessors T &X() { return (*this)[0]; } const T &X() const { return (*this)[0]; } @@ -75,7 +85,6 @@ namespace FasTC { } // Swizzle - #ifdef _VEX_ENABLE_SWIZZLE_ _VEX_VEC2_SWIZZLE_DEF(X, X) _VEX_VEC2_SWIZZLE_DEF(X, Y) _VEX_VEC2_SWIZZLE_DEF(X, Z) @@ -113,7 +122,6 @@ namespace FasTC { _VEX_VEC3_SWIZZLE_DEF(Z, Z, X) _VEX_VEC3_SWIZZLE_DEF(Z, Z, Y) _VEX_VEC3_SWIZZLE_DEF(Z, Z, Z) - #endif // _VEX_ENABLE_SWIZZLE_ }; REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector3); diff --git a/Base/include/Vector4.h b/Base/include/Vector4.h index bf5311d..5f0dbbc 100644 --- a/Base/include/Vector4.h +++ b/Base/include/Vector4.h @@ -28,10 +28,8 @@ #include "TexCompTypes.h" #include "Vector3.h" -#ifdef _VEX_ENABLE_SWIZZLE_ #define _VEX_VEC4_SWIZZLE_DEF(X, Y, Z, W) \ Vector4 X##Y##Z##W() const { return Vector4( X(), Y(), Z(), W() ); } -#endif // _VEX_ENABLE_SWIZZLE_ namespace FasTC { @@ -45,6 +43,12 @@ namespace FasTC { Z() = z; W() = w; } + + explicit Vector4(const T *_vec) { + for(int i = 0; i < 4; i++) { + this->vec[i] = _vec[i]; + } + } // Overloaded functions template @@ -56,6 +60,12 @@ namespace FasTC { return *this; } + template + Vector4 &operator=(const _T *v) { + VectorBase::operator=(v); + return *this; + } + // Accessors T &X() { return (*this)[0]; } const T &X() const { return (*this)[0]; } @@ -70,7 +80,6 @@ namespace FasTC { const T &W() const { return (*this)[3]; } // Swizzle - #ifdef _VEX_ENABLE_SWIZZLE_ _VEX_VEC2_SWIZZLE_DEF(X, X) _VEX_VEC2_SWIZZLE_DEF(X, Y) _VEX_VEC2_SWIZZLE_DEF(X, Z) @@ -409,7 +418,6 @@ namespace FasTC { _VEX_VEC4_SWIZZLE_DEF(W, W, W, Y) _VEX_VEC4_SWIZZLE_DEF(W, W, W, Z) _VEX_VEC4_SWIZZLE_DEF(W, W, W, W) - #endif // _VEX_ENABLE_SWIZZLE_ }; REGISTER_ONE_TEMPLATE_VECTOR_TYPE(Vector4); diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp index 45c05a4..f8173a9 100644 --- a/Base/test/TestVector.cpp +++ b/Base/test/TestVector.cpp @@ -215,3 +215,204 @@ TEST(VectorBase, Addition) { EXPECT_NEAR(af[0], -3.9f, kEpsilon); EXPECT_NEAR(af[1], 1.2f, kEpsilon); } + +//////////////////////////////////////////////////////////////////////////////// +// +// Vec2 +// +//////////////////////////////////////////////////////////////////////////////// + +#include "Vector2.h" + +TEST(Vector2, BaseFunctionality) { + FasTC::Vec2f v2f; + FasTC::Vec2d v2d; + + v2f = v2d; + EXPECT_NEAR(v2f[0], v2d[0], kEpsilon); + EXPECT_NEAR(v2f[1], v2d[1], kEpsilon); +} + +TEST(Vector2, Accessors) { + float fv[2] = { 1.0f, 2.0f }; + FasTC::Vec2f v2f (fv); + EXPECT_EQ(v2f.X(), 1.0f); + EXPECT_EQ(v2f.Y(), 2.0f); + + v2f.X() = 4.0f; + v2f.Y() = 5.0f; + + EXPECT_EQ(v2f.X(), 4.0f); + EXPECT_EQ(v2f.Y(), 5.0f); +} + +TEST(Vector2, Addition) { + float fv[2] = { 1.0f, 2.0f }; + FasTC::Vec2f v2f (fv); + + double dv[2] = { 4.3, -10.2 }; + FasTC::Vec2d v2d (dv); + + EXPECT_NEAR((v2f + v2d).X(), 5.3, kEpsilon); + EXPECT_NEAR((v2f + v2d).Y(), -8.2, kEpsilon); +} + +TEST(Vector2, Swizzle) { + float fv[2] = {1.0f, 2.0f}; + FasTC::Vec2f v; + v = fv; + + EXPECT_EQ(v.XX().X(), 1.0f); + EXPECT_EQ(v.XX().Y(), 1.0f); + EXPECT_EQ(v.YY().X(), 2.0f); + EXPECT_EQ(v.YY().Y(), 2.0f); + EXPECT_EQ(v.YX().X(), 2.0f); + EXPECT_EQ(v.YX().Y(), 1.0f); + EXPECT_EQ(v.XY().X(), 1.0f); + EXPECT_EQ(v.XY().Y(), 2.0f); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Vec3 +// +//////////////////////////////////////////////////////////////////////////////// + +#include "Vector3.h" + +TEST(Vector3, BaseFunctionality) { + FasTC::Vec3f vf; + FasTC::Vec3d vd; + + vf = vd; + for(int i = 0; i < 3; i++) { + EXPECT_NEAR(vf[i], vd[i], kEpsilon); + } +} + +TEST(Vector3, Accessors) { + float fv[3] = { 1.0f, 2.0f, 3.0f }; + FasTC::Vec3f v3f (fv); + EXPECT_EQ(v3f.X(), 1.0f); + EXPECT_EQ(v3f.Y(), 2.0f); + EXPECT_EQ(v3f.Z(), 3.0f); + + v3f.X() = 4.0f; + v3f.Y() = 5.0f; + v3f.Z() = 6.0f; + + EXPECT_EQ(v3f.X(), 4.0f); + EXPECT_EQ(v3f.Y(), 5.0f); + EXPECT_EQ(v3f.Z(), 6.0f); +} + +TEST(Vector3, Addition) { + float fv[3] = { 1.0f, 2.0f, 3.0f }; + FasTC::Vec3f v3f (fv); + + double dv[3] = { 4.3, -10.2, 0.0f }; + FasTC::Vec3d v3d (dv); + + EXPECT_NEAR((v3f + v3d).X(), 5.3, kEpsilon); + EXPECT_NEAR((v3f + v3d).Y(), -8.2, kEpsilon); + EXPECT_NEAR((v3f + v3d).Z(), 3.0, kEpsilon); +} + +TEST(Vector3, Swizzle) { + float fv[3] = {1.0f, 2.0f, 3.0f}; + FasTC::Vec3f v; + v = fv; + + EXPECT_EQ(v.XXX().Y(), 1.0f); + EXPECT_EQ(v.YZX().X(), 2.0f); + EXPECT_EQ(v.ZZY().Z(), 2.0f); + EXPECT_EQ(v.ZYZ().X(), 3.0f); +} + +TEST(Vector3, CrossProduct) { + float fv[3] = {1.0f, 2.0f, 3.0f}; + FasTC::Vec3f v1 (fv); + FasTC::Vec3f v2 = v1; + std::swap(v1.X(), v1.Z()); + + // Right handed coordinate system... + FasTC::Vec3f r = v1.Cross(v2); + EXPECT_NEAR(r.X(), 4.0f, kEpsilon); + EXPECT_NEAR(r.Y(), -8.0f, kEpsilon); + EXPECT_NEAR(r.Z(), 4.0f, kEpsilon); + + v1.X() = v1.Y() = v2.X() = v2.Z() = 0.0f; + v1.Z() = v2.Y() = 1.0f; + + r = v1.Cross(v2); + EXPECT_EQ(r.X(), -1.0f); + EXPECT_EQ(r.Y(), 0.0f); + EXPECT_EQ(r.Z(), 0.0f); + + r = v2.Cross(v1); + EXPECT_EQ(r.X(), 1.0f); + EXPECT_EQ(r.Y(), 0.0f); + EXPECT_EQ(r.Z(), 0.0f); +} + +//////////////////////////////////////////////////////////////////////////////// +// +// Vec4 +// +//////////////////////////////////////////////////////////////////////////////// + +#include "Vector4.h" + +TEST(Vector4, BaseFunctionality) { + FasTC::Vec4f vf; + FasTC::Vec4d vd; + + vf = vd; + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(vf[i], vd[i], kEpsilon); + } +} + +TEST(Vector4, Accessors) { + float fv[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; + FasTC::Vec4f v4f (fv); + EXPECT_EQ(v4f.X(), 1.0f); + EXPECT_EQ(v4f.Y(), 2.0f); + EXPECT_EQ(v4f.Z(), 3.0f); + EXPECT_EQ(v4f.W(), 4.0f); + + v4f.X() = 5.0f; + v4f.Y() = 6.0f; + v4f.Z() = 7.0f; + v4f.W() = 8.0f; + + EXPECT_EQ(v4f.X(), 5.0f); + EXPECT_EQ(v4f.Y(), 6.0f); + EXPECT_EQ(v4f.Z(), 7.0f); + EXPECT_EQ(v4f.W(), 8.0f); +} + +TEST(Vector4, Addition) { + float fv[4] = { 1.0f, 2.0f, 3.0f, 4.0f }; + FasTC::Vec4f v4f (fv); + + double dv[4] = { 4.3, -10.2, 0.0f, -22.0f }; + FasTC::Vec4d v3d (dv); + + EXPECT_NEAR((v4f + v3d).X(), 5.3, kEpsilon); + EXPECT_NEAR((v4f + v3d).Y(), -8.2, kEpsilon); + EXPECT_NEAR((v4f + v3d).Z(), 3.0, kEpsilon); + EXPECT_NEAR((v4f + v3d).W(), -18.0, kEpsilon); +} + +TEST(Vector4, Swizzle) { + float fv[4] = {1.0f, 2.0f, 3.0f, 4.0f}; + FasTC::Vec4f v; + v = fv; + + EXPECT_EQ(v.XXXX().Y(), 1.0f); + EXPECT_EQ(v.YZXW().X(), 2.0f); + EXPECT_EQ(v.ZWY().Z(), 2.0f); + EXPECT_EQ(v.ZZ().X(), 3.0f); + EXPECT_EQ(v.WWXY().W(), 2.0f); +} From 0875ee0ddbfaf306961e08dcf3ebf66a6c146669 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Sun, 16 Feb 2014 18:29:08 -0500 Subject: [PATCH 14/30] Constify --- Base/include/VectorBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index 50f9ef1..e682377 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -46,7 +46,7 @@ namespace FasTC { for(int i = 0; i < N; i++) vec[i] = other[i]; } - explicit VectorBase(T *_vec) { + explicit VectorBase(const T *_vec) { for(int i = 0; i < N; i++) { vec[i] = _vec[i]; } From 4fc75f22dc268cb624970ff2421fe26c3bd6e517 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Mon, 17 Feb 2014 13:02:43 -0500 Subject: [PATCH 15/30] Fix vector operators to avoid needing overloads --- Base/include/Pixel.h | 35 ----------------------------------- Base/include/VectorBase.h | 16 ++++++++-------- 2 files changed, 8 insertions(+), 43 deletions(-) diff --git a/Base/include/Pixel.h b/Base/include/Pixel.h index 1f6afe2..31833b9 100644 --- a/Base/include/Pixel.h +++ b/Base/include/Pixel.h @@ -159,41 +159,6 @@ class Pixel : public Vector4 { }; REGISTER_VECTOR_TYPE(Pixel); -// Overload operators so that we can preserve bit depths... -template -static inline Pixel ScalarMultiply(const Pixel &p, const ScalarType &s) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) - a(i) = p(i) * s; - return a; -} - -template -static inline Pixel ScalarDivide(const Pixel &p, const ScalarType &s) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) - a(i) = p(i) / s; - return a; -} - -template -static inline Pixel VectorAddition(const Pixel &p, const VectorType &v) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) { - a(i) += v(i); - } - return a; -} - -template -static inline Pixel VectorSubtraction(const Pixel &p, const VectorType &v) { - Pixel a(p); - for(int i = 0; i < Pixel::Size; i++) { - a(i) -= v(i); - } - return a; -} - } // namespace FasTC #endif // BASE_INCLUDE_PIXEL_H_ diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index e682377..f1d9413 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -102,9 +102,9 @@ namespace FasTC { template static inline VectorTypeOne VectorAddition(const VectorTypeOne &v1, const VectorTypeTwo &v2) { - VectorTypeOne a; + VectorTypeOne a(v1); for(int i = 0; i < VectorTypeOne::Size; i++) { - a(i) = v1(i) + v2(i); + a(i) += v2(i); } return a; } @@ -124,9 +124,9 @@ namespace FasTC { template static inline VectorTypeOne VectorSubtraction(const VectorTypeOne &v1, const VectorTypeTwo &v2) { - VectorTypeOne a; + VectorTypeOne a(v1); for(int i = 0; i < VectorTypeOne::Size; i++) { - a(i) = v1(i) - v2(i); + a(i) -= v2(i); } return a; } @@ -204,9 +204,9 @@ namespace FasTC { template static inline VectorType ScalarMultiply(const VectorType &v, const ScalarType &s) { - VectorType a; + VectorType a(v); for(int i = 0; i < VectorType::Size; i++) - a(i) = static_cast(v(i) * s); + a(i) *= static_cast(s); return a; } @@ -221,9 +221,9 @@ namespace FasTC { template static inline VectorType ScalarDivide(const VectorType &v, const ScalarType &s) { - VectorType a; + VectorType a(v); for(int i = 0; i < VectorType::Size; i++) - a(i) = static_cast(v(i) / s); + a(i) /= static_cast(s); return a; } From 9dc23db287bf61d65744561320231d1fe611fc06 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Tue, 18 Feb 2014 13:25:29 -0500 Subject: [PATCH 16/30] Add YCoCg pixel type --- Base/include/Pixel.h | 24 +++++++++++++++++++++++- Base/src/Pixel.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Base/include/Pixel.h b/Base/include/Pixel.h index 31833b9..2f02b64 100644 --- a/Base/include/Pixel.h +++ b/Base/include/Pixel.h @@ -59,7 +59,7 @@ namespace FasTC { class Pixel : public Vector4 { - private: + protected: typedef uint16 ChannelType; typedef Vector4 VectorType; uint8 m_BitDepth[4]; @@ -159,6 +159,28 @@ class Pixel : public Vector4 { }; REGISTER_VECTOR_TYPE(Pixel); +class YCoCgPixel : public Pixel { + private: + void ToYCoCg(); + + public: + YCoCgPixel() : Pixel() { } + explicit YCoCgPixel(uint32 rgba) : Pixel(rgba) { ToYCoCg(); } + explicit YCoCgPixel(const Pixel &p) : Pixel(p) { ToYCoCg(); } + + Pixel ToRGBA() const; + + float ToIntensity() const { return ConvertChannelToFloat(R(), 8); } + uint32 Pack() const { return ToRGBA().Pack(); } + void Unpack(uint32 rgba) { Pixel::Unpack(rgba); ToYCoCg(); } + + const ChannelType &Co() const { return Z(); } + ChannelType &Co() { return Z(); } + const ChannelType &Cg() const { return W(); } + ChannelType &Cg() { return W(); } +}; +REGISTER_VECTOR_TYPE(YCoCgPixel); + } // namespace FasTC #endif // BASE_INCLUDE_PIXEL_H_ diff --git a/Base/src/Pixel.cpp b/Base/src/Pixel.cpp index 8364dd2..7806292 100644 --- a/Base/src/Pixel.cpp +++ b/Base/src/Pixel.cpp @@ -56,6 +56,11 @@ #include #include +template +static inline T Clamp(const T &v, const T &_min, const T &_max) { + return std::max(_min, std::min(v, _max)); +} + namespace FasTC { void Pixel::FromBits(const uint8 *bits, @@ -260,4 +265,30 @@ namespace FasTC { return ok; } + void YCoCgPixel::ToYCoCg() { + int16 Y = ((R() + (G() << 1) + B()) + 2) >> 2; + int16 Co = (R() - B() + 1) >> 1; + int16 Cg = ((-R() + (G() << 1) - B()) + 2) >> 2; + + this->Y() = Clamp(Y, 0, 255); + this->Co() = Clamp(Co + 128, 0, 255); + this->Cg() = Clamp(Cg + 128, 0, 255); + } + + Pixel YCoCgPixel::ToRGBA() const { + int16 Co = this->Co() - 128; + int16 Cg = this->Cg() - 128; + + int16 R = Y() + (Co - Cg); + int16 G = Y() + Cg; + int16 B = Y() - (Co + Cg); + + Pixel p; + p.R() = Clamp(R, 0, 255); + p.G() = Clamp(G, 0, 255); + p.B() = Clamp(B, 0, 255); + p.A() = A(); + return p; + } + } // namespace FasTC From 366a7cdfe485f256bec265e1a2ba8d818f187f1c Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 19 Feb 2014 19:35:29 -0500 Subject: [PATCH 17/30] Add some YCoCg tests --- Base/test/TestPixel.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/Base/test/TestPixel.cpp b/Base/test/TestPixel.cpp index 9d95fd9..fc97dca 100644 --- a/Base/test/TestPixel.cpp +++ b/Base/test/TestPixel.cpp @@ -278,3 +278,33 @@ TEST(Pixel, ScaleColor) { EXPECT_EQ(bd[i], newBitDepth[i]); } } + +TEST(YCoCgPixel, Conversion) { + + FasTC::Pixel p; + p.R() = 127; + p.G() = 127; + p.B() = 127; + p.A() = 255; + + FasTC::YCoCgPixel yp (p); + EXPECT_EQ(yp.Y(), 127); + EXPECT_EQ(yp.Co(), 128); + EXPECT_EQ(yp.Cg(), 128); +} + +TEST(YCoCgPixel, ConvertBack) { + FasTC::Pixel p; + + p.R() = 241; + p.G() = 22; + p.B() = 102; + p.A() = 124; + + FasTC::YCoCgPixel yp (p); + FasTC::Pixel bp = yp.ToRGBA(); + + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(p[i], bp[i], 1); + } +} From 2d7ee21fb781ffb346b54e514469338e0c5022bb Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Wed, 19 Feb 2014 19:36:28 -0500 Subject: [PATCH 18/30] Let the compiler choose what precision we want to do the vector-scalar multiplication/division in. --- Base/include/VectorBase.h | 4 ++-- Base/test/TestVector.cpp | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index f1d9413..596df02 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -206,7 +206,7 @@ namespace FasTC { static inline VectorType ScalarMultiply(const VectorType &v, const ScalarType &s) { VectorType a(v); for(int i = 0; i < VectorType::Size; i++) - a(i) *= static_cast(s); + a(i) = static_cast(a(i) * s); return a; } @@ -223,7 +223,7 @@ namespace FasTC { static inline VectorType ScalarDivide(const VectorType &v, const ScalarType &s) { VectorType a(v); for(int i = 0; i < VectorType::Size; i++) - a(i) /= static_cast(s); + a(i) = static_cast(a(i) / s); return a; } diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp index f8173a9..e6637e1 100644 --- a/Base/test/TestVector.cpp +++ b/Base/test/TestVector.cpp @@ -190,16 +190,26 @@ TEST(VectorBase, Scaling) { v2fd = v2f / 3; EXPECT_NEAR(v2fd[0], 1.0f / 3.0f, kEpsilon); EXPECT_NEAR(v2fd[1], 1.0f, kEpsilon); + + unsigned uv[2] = {1, 3}; + FasTC::VectorBase v2u (uv); + FasTC::VectorBase v2ud = v2u * 0.5; + EXPECT_EQ(v2ud[0], 0); + EXPECT_EQ(v2ud[1], 1); + + v2ud = v2u / 0.5f; + EXPECT_EQ(v2ud[0], 2); + EXPECT_EQ(v2ud[1], 6); } TEST(VectorBase, Addition) { float fv[2] = {1.1f, 3.2f}; FasTC::VectorBase v2f (fv); - unsigned uv[2] = {5, 2}; - FasTC::VectorBase v2u (uv); + int uv[2] = {5, 2}; + FasTC::VectorBase v2u (uv); - FasTC::VectorBase au = v2u + v2f; + FasTC::VectorBase au = v2u + v2f; EXPECT_EQ(au[0], 6); EXPECT_EQ(au[1], 5); @@ -209,7 +219,7 @@ TEST(VectorBase, Addition) { au = v2u - v2f; EXPECT_EQ(au[0], 3); - EXPECT_EQ(au[1], 0); + EXPECT_EQ(au[1], -1); af = v2f - v2u; EXPECT_NEAR(af[0], -3.9f, kEpsilon); From 62cce58c2ff9abd34c103daf2ae61d3aebe427c4 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 14:49:35 -0500 Subject: [PATCH 19/30] Fix some of the vector multiplication and divide routines. In general, we want the scalar division of vectors and matrices to have the matrix come first and the scalar come second. It doesn't make sense to divide a scalar by a vector or to divide a matrix by a vector, so these should now produce errors at compile time. Also, make sure to add additional types that can be multiplied together using the * operator. If we multiply two vectors together, that's a dot product. The size restrictions should be enforced at compile time by the template parameters for VectorBase::Dot In this way, we can support vector/matrix multiplication by retaining the * operator as well. --- Base/include/VectorBase.h | 168 ++++++++++++++++++++++++-------------- Base/test/TestVector.cpp | 3 + 2 files changed, 111 insertions(+), 60 deletions(-) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index 596df02..46bc194 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -31,6 +31,12 @@ namespace FasTC { + enum EVectorType { + eVectorType_Scalar, + eVectorType_Vector, + eVectorType_Matrix + }; + template class VectorBase { protected: @@ -146,62 +152,29 @@ namespace FasTC { template class VectorTraits { public: - static const bool IsVector = false; + static const EVectorType kVectorType = eVectorType_Scalar; }; template class VectorTraits > { public: - static const bool IsVector = true; + static const EVectorType kVectorType = eVectorType_Vector; }; - #define REGISTER_VECTOR_TYPE(TYPE) \ - template<> \ - class VectorTraits< TYPE > { \ - public: \ - static const bool IsVector = true; \ + #define REGISTER_VECTOR_TYPE(TYPE) \ + template<> \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Vector; \ } - #define REGISTER_ONE_TEMPLATE_VECTOR_TYPE(TYPE) \ - template \ - class VectorTraits< TYPE > { \ - public: \ - static const bool IsVector = true; \ + #define REGISTER_ONE_TEMPLATE_VECTOR_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Vector; \ } - template - class VectorSwitch { - private: - const TypeOne &m_A; - const TypeTwo &m_B; - public: - typedef TypeOne VectorType; - typedef TypeTwo ScalarType; - - VectorSwitch(const TypeOne &a, const TypeTwo &b) - : m_A(a), m_B(b) { } - - const VectorType &GetVector() { return m_A; } - const ScalarType &GetScalar() { return m_B; } - }; - - template - class VectorSwitch { - private: - const TypeOne &m_A; - const TypeTwo &m_B; - - public: - typedef TypeTwo VectorType; - typedef TypeOne ScalarType; - - VectorSwitch(const TypeOne &a, const TypeTwo &b) - : m_A(a), m_B(b) { } - - const VectorType &GetVector() { return m_B; } - const ScalarType &GetScalar() { return m_A; } - }; - template static inline VectorType ScalarMultiply(const VectorType &v, const ScalarType &s) { VectorType a(v); @@ -210,13 +183,97 @@ namespace FasTC { return a; } + template< + EVectorType kVectorTypeOne, + EVectorType kVectorTypeTwo, + typename TypeOne, + typename TypeTwo> + class MultSwitch { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + public: + typedef TypeOne ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() { return m_A * m_B; } + }; + + template + class MultSwitch< + eVectorType_Scalar, + eVectorType_Vector, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef TypeTwo ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() { return ScalarMultiply(m_B, m_A); } + }; + + template + class MultSwitch< + eVectorType_Vector, + eVectorType_Scalar, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef TypeOne ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() { return ScalarMultiply(m_A, m_B); } + }; + + template + class MultSwitch< + eVectorType_Vector, + eVectorType_Vector, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef typename TypeOne::ScalarType ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() { return m_A.Dot(m_B); } + }; + template static inline - typename VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo >::VectorType + typename MultSwitch< + VectorTraits::kVectorType, + VectorTraits::kVectorType, + TypeOne, TypeTwo + >::ResultType operator*(const TypeOne &v1, const TypeTwo &v2) { - typedef VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo > VSwitch; - VSwitch s(v1, v2); - return ScalarMultiply(s.GetVector(), s.GetScalar()); + typedef MultSwitch< + VectorTraits::kVectorType, + VectorTraits::kVectorType, + TypeOne, TypeTwo + > VSwitch; + return VSwitch(v1, v2).GetMultiplication(); + } + + template + static inline VectorType &operator*=(VectorType &v, const ScalarType &s) { + return v = v * s; } template @@ -228,17 +285,8 @@ namespace FasTC { } template - static inline - typename VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo >::VectorType - operator/(const TypeOne &v1, const TypeTwo &v2) { - typedef VectorSwitch< VectorTraits::IsVector, TypeOne, TypeTwo > VSwitch; - VSwitch s(v1, v2); - return ScalarDivide(s.GetVector(), s.GetScalar()); - } - - template - static inline VectorType &operator*=(VectorType &v, const ScalarType &s) { - return v = ScalarMultiply(v, s); + static inline TypeOne operator/(const TypeOne &v1, const TypeTwo &v2) { + return ScalarDivide(v1, v2); } template diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp index e6637e1..f2f2f53 100644 --- a/Base/test/TestVector.cpp +++ b/Base/test/TestVector.cpp @@ -135,6 +135,9 @@ TEST(VectorBase, DotProduct) { EXPECT_EQ(v5i.Dot(v5u), 10); EXPECT_EQ(v5u.Dot(v5i), 10); + + EXPECT_EQ(v5i * v5u, 10); + EXPECT_EQ(v5u * v5i, 10); } TEST(VectorBase, Length) { From 1b7691993d6ff265a5ee1733d13598df97085fd7 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 15:34:12 -0500 Subject: [PATCH 20/30] Add initial matrix tests --- Base/include/MatrixBase.h | 153 +++++++++++++------------------------- Base/test/CMakeLists.txt | 6 +- Base/test/TestMatrix.cpp | 134 +++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+), 105 deletions(-) create mode 100644 Base/test/TestMatrix.cpp diff --git a/Base/include/MatrixBase.h b/Base/include/MatrixBase.h index 3182b4b..195250f 100644 --- a/Base/include/MatrixBase.h +++ b/Base/include/MatrixBase.h @@ -30,99 +30,45 @@ namespace FasTC { template - class MatrixBase { - protected: - - // Vector representation - static const int kNumElements = nRows * nCols; - T mat[kNumElements]; - + class MatrixBase : public VectorBase { + private: + typedef VectorBase Base; public: - + static const int Size = Base::Size; + // Constructors MatrixBase() { } MatrixBase(const MatrixBase &other) { - for(int i = 0; i < kNumElements; i++) { - mat[i] = other[i]; + for(int i = 0; i < Size; i++) { + (*this)[i] = other[i]; } } // Accessors - T &operator()(int idx) { return mat[idx]; } - const T &operator()(int idx) const { return mat[idx]; } - T &operator()(int r, int c) { return mat[r * nCols + c]; } - const T &operator() const (int r, int c) { return mat[r * nCols + c]; } + T &operator()(int idx) { return Base::operator()(idx); } + T &operator[](int idx) { return Base::operator[](idx); } + const T &operator()(int idx) const { return Base::operator()(idx); } + const T &operator[](int idx) const { return Base::operator[](idx); } - T &operator[](int idx) { return mat[idx]; } - const T &operator[](int idx) const { return mat[idx]; } + T &operator()(int r, int c) { return (*this)[r * nCols + c]; } + const T &operator() (int r, int c) const { return (*this)[r * nCols + c]; } - // Operators - template - MatrixBase operator+(const MatrixBase<_T, nRows, nCols> &m) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] + m[i]; - } - return a; - } - - template - MatrixBase &operator+=(const MatrixBase<_T, nRows, nCols> &m) { - for(int i = 0; i < kNumElements; i++) { - mat[i] += m[i]; - } + // Allow casts to the respective array representation... + operator const T *() const { return this->vec; } + MatrixBase &operator=(const T *v) { + for(int i = 0; i < Size; i++) + (*this)[i] = v[i]; return *this; } + // Allows casting to other vector types if the underlying type system does as well... template - MatrixBase operator-(const MatrixBase<_T, nRows, nCols> &m) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] - m[i]; + operator MatrixBase<_T, nRows, nCols>() const { + MatrixBase<_T, nRows, nCols> ret; + for(int i = 0; i < Size; i++) { + ret[i] = static_cast<_T>(this->vec[i]); } - return a; - } - - template - MatrixBase &operator-=(const MatrixBase<_T, nRows, nCols> &m) { - for(int i = 0; i < kNumElements; i++) { - mat[i] -= m[i]; - } - return *this; - } - - template - MatrixBase operator*(_T s) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] * s; - } - return a; - } - - template - MatrixBase &operator*=(_T s) { - for(int i = 0; i < kNumElements; i++) { - mat[i] *= s; - } - return *this; - } - - template - MatrixBase operator/(_T s) { - MatrixBase a; - for(int i = 0; i < kNumElements; i++) { - a[i] = mat[i] / s; - } - return a; - } - - template - MatrixBase &operator/=(_T s) { - for(int i = 0; i < kNumElements; i++) { - mat[i] /= s; - } - return *this; + return ret; } // Matrix multiplication @@ -152,40 +98,41 @@ namespace FasTC { return result; } - // Outer product... - template - friend MatrixBase<_T, N, M> operator^( - const VectorBase<_T, N> &a, - const VectorBase<_U, M> &b - ) { - MatrixBase<_T, N, M> result; - - for(int i = 0; i < N; i++) - for(int j = 0; j < M; j++) - result(i, j) = a[i] * b[j]; - - return result; - } - - template - friend MatrixBase<_T, N, M> OuterProduct( - const VectorBase<_T, N> &a, - const VectorBase<_U, M> &b - ) { - return a ^ b; - } - // Double dot product template T DDot(const MatrixBase<_T, nRows, nCols> &m) { T result = 0; - for(int i = 0; i < kNumElements; i++) { - result += mat[i] * m[i]; + for(int i = 0; i < Size; i++) { + result += (*this)[i] * m[i]; } return result; } }; + + // Outer product... + template + MatrixBase<_T, N, M> operator^( + const VectorBase<_T, N> &a, + const VectorBase<_U, M> &b + ) { + MatrixBase<_T, N, M> result; + + for(int i = 0; i < N; i++) + for(int j = 0; j < M; j++) + result(i, j) = a[i] * b[j]; + + return result; + } + + template + MatrixBase<_T, N, M> OuterProduct( + const VectorBase<_T, N> &a, + const VectorBase<_U, M> &b + ) { + return a ^ b; + } + }; #endif // BASE_INCLUDE_MATRIXBASE_H_ diff --git a/Base/test/CMakeLists.txt b/Base/test/CMakeLists.txt index 8295630..25deb87 100644 --- a/Base/test/CMakeLists.txt +++ b/Base/test/CMakeLists.txt @@ -55,7 +55,7 @@ INCLUDE_DIRECTORIES(${FasTC_BINARY_DIR}/Base/include ) INCLUDE_DIRECTORIES(${FasTC_SOURCE_DIR}/GTest/include) SET(TESTS - Vector Pixel Image Color + Vector Matrix Pixel Image Color ) FOREACH(TEST ${TESTS}) @@ -70,7 +70,9 @@ FOREACH(TEST ${TESTS}) ADD_EXECUTABLE(${TEST_NAME} ${TEST_MODULE}) # Vector tests need to use uninitialized variables - IF(${TEST_NAME} STREQUAL "Test_Base_Vector") + IF((${TEST_NAME} STREQUAL "Test_Base_Vector") + OR + (${TEST_NAME} STREQUAL "Test_Base_Matrix")) IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUXX) SET_TARGET_PROPERTIES( ${TEST_NAME} diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp new file mode 100644 index 0000000..7345931 --- /dev/null +++ b/Base/test/TestMatrix.cpp @@ -0,0 +1,134 @@ +/* FasTC + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. + * + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . + * + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. + * + * Please send all BUG REPORTS to . + * + * The authors may be contacted via: + * + * Pavel Krajcevski + * Dept of Computer Science + * 201 S Columbia St + * Frederick P. Brooks, Jr. Computer Science Bldg + * Chapel Hill, NC 27599-3175 + * USA + * + * + */ + +#include "gtest/gtest.h" +#include "MatrixBase.h" + +static const float kEpsilon = 1e-6; + +TEST(MatrixBase, Constructors) { + FasTC::MatrixBase m3f; + FasTC::MatrixBase m1d; + FasTC::MatrixBase m7i; + FasTC::MatrixBase m16u; + +#define TEST_VECTOR_COPY_CONS(mat, t, n, m) \ + do { \ + FasTC::MatrixBase d##mat (mat); \ + for(int i = 0; i < n*m; i++) { \ + EXPECT_EQ(d##mat [i], mat[i]); \ + } \ + } while(0) \ + + TEST_VECTOR_COPY_CONS(m3f, float, 3, 4); + TEST_VECTOR_COPY_CONS(m1d, double, 1, 1); + TEST_VECTOR_COPY_CONS(m7i, int, 7, 200); + TEST_VECTOR_COPY_CONS(m16u, unsigned, 16, 16); + +#undef TEST_VECTOR_COPY_CONS +} + +TEST(MatrixBase, Accessors) { + FasTC::MatrixBase v3f; + v3f[0] = 1.0f; + v3f[1] = -2.3f; + v3f[2] = 1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], v3f(i)); + } + + v3f(0) = -1.0f; + v3f(1) = 2.3f; + v3f(2) = -1000; + + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f(i), v3f[i]); + } +} + +TEST(MatrixBase, PointerConversion) { + FasTC::MatrixBase v3f; + v3f(0,0) = 1.0f; + v3f(0,1) = -2.3f; + v3f(0,2) = 1000.0f; + v3f(1,0) = 1.0f; + v3f(1,1) = -2.3f; + v3f(1,2) = 1000.0f; + + float cmp[6] = { 1.0f, -2.3f, 1000.0f, 1.0f, -2.3f, 1000.0f }; + const float *v3fp = v3f; + int result = memcmp(cmp, v3fp, 6 * sizeof(float)); + EXPECT_EQ(result, 0); + + cmp[0] = -1.0f; + cmp[1] = 2.3f; + cmp[2] = 1000.0f; + cmp[3] = -1.0f; + cmp[4] = 2.3f; + cmp[5] = 1000.0f; + v3f = cmp; + for(int i = 0; i < 3; i++) { + EXPECT_EQ(v3f[i], cmp[i]); + } +} + +TEST(MatrixBase, CastVector) { + FasTC::MatrixBase v3f; + FasTC::MatrixBase v3d = v3f; + FasTC::MatrixBase v3i = v3f; + for(int i = 0; i < 3*2; i++) { + EXPECT_EQ(v3d(i), static_cast(v3f(i))); + EXPECT_EQ(v3i(i), static_cast(v3f(i))); + } +} + From 7ed5c134059ac2279e35ad90d0639b7f4c7e3720 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 15:36:59 -0500 Subject: [PATCH 21/30] Allow additional indexable types Instead of using operator() to index into the second operand of the VectorAddition function, use operator[]. This way we can add to pointers and std::vector types as well. --- Base/include/VectorBase.h | 4 ++-- Base/test/TestVector.cpp | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index 46bc194..c3df4b4 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -110,7 +110,7 @@ namespace FasTC { const VectorTypeTwo &v2) { VectorTypeOne a(v1); for(int i = 0; i < VectorTypeOne::Size; i++) { - a(i) += v2(i); + a(i) += v2[i]; } return a; } @@ -132,7 +132,7 @@ namespace FasTC { const VectorTypeTwo &v2) { VectorTypeOne a(v1); for(int i = 0; i < VectorTypeOne::Size; i++) { - a(i) -= v2(i); + a(i) -= v2[i]; } return a; } diff --git a/Base/test/TestVector.cpp b/Base/test/TestVector.cpp index f2f2f53..7735fdc 100644 --- a/Base/test/TestVector.cpp +++ b/Base/test/TestVector.cpp @@ -216,6 +216,10 @@ TEST(VectorBase, Addition) { EXPECT_EQ(au[0], 6); EXPECT_EQ(au[1], 5); + au = v2u + fv + uv; + EXPECT_EQ(au[0], 11); + EXPECT_EQ(au[1], 7); + FasTC::VectorBase af = v2f + v2u; EXPECT_NEAR(af[0], 6.1f, kEpsilon); EXPECT_NEAR(af[1], 5.2f, kEpsilon); From 2af172e5e599318476ed71b52f160724abeb67a0 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 15:47:14 -0500 Subject: [PATCH 22/30] Add power method iteration for square matrices --- Base/include/MatrixSquare.h | 53 ++++++++++++++++++++++++++++++++++--- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/Base/include/MatrixSquare.h b/Base/include/MatrixSquare.h index 7fdfb48..8c20752 100644 --- a/Base/include/MatrixSquare.h +++ b/Base/include/MatrixSquare.h @@ -35,11 +35,58 @@ namespace FasTC { // Constructors MatrixSquare() { } - MatrixSquare(const MatrixBase &other) { - for(int i = 0; i < kNumElements; i++) { - mat[i] = other[i]; + MatrixSquare(const MatrixSquare &other) + : MatrixBase(other) { } + MatrixSquare(const MatrixBase &other) + : MatrixBase(other) { } + + // Does power iteration to determine the principal eigenvector and eigenvalue. + // Returns them in eigVec and eigVal after kMaxNumIterations + int PowerMethod(VectorBase &eigVec, T *eigVal = NULL, + const int kMaxNumIterations = 200) { + int numIterations = 0; + + // !SPEED! Find eigenvectors by using the power method. This is good because the + // matrix is only 4x4, which allows us to use SIMD... + VectorBase b; + for(int i = 0; i < N; i++) + b[i] = T(1.0); + + b /= b.Length(); + + bool fixed = false; + numIterations = 0; + while(!fixed && ++numIterations < kMaxNumIterations) { + + VectorBase newB = (*this).operator*(b); + + // !HACK! If the principal eigenvector of the covariance matrix + // converges to zero, that means that the points lie equally + // spaced on a sphere in this space. In this (extremely rare) + // situation, just choose a point and use it as the principal + // direction. + const float newBlen = newB.Length(); + if(newBlen < 1e-10) { + eigVec = b; + if(eigVal) *eigVal = 0.0; + return numIterations; + } + + T len = newB.Length(); + newB /= len; + if(eigVal) + *eigVal = len; + + if(fabs(1.0f - (b.Dot(newB))) < 1e-5) + fixed = true; + + b = newB; } + + eigVec = b; + return numIterations; } + }; }; From 4ca6141be6f88172aca003fa75507cc15c11cecc Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 15:47:48 -0500 Subject: [PATCH 23/30] Add simple 4x4 matrix file --- Base/include/Matrix4x4.h | 75 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 Base/include/Matrix4x4.h diff --git a/Base/include/Matrix4x4.h b/Base/include/Matrix4x4.h new file mode 100644 index 0000000..4a21bf9 --- /dev/null +++ b/Base/include/Matrix4x4.h @@ -0,0 +1,75 @@ +/* FasTC + * Copyright (c) 2014 University of North Carolina at Chapel Hill. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for educational, research, and non-profit purposes, without + * fee, and without a written agreement is hereby granted, provided that the + * above copyright notice, this paragraph, and the following four paragraphs + * appear in all copies. + * + * Permission to incorporate this software into commercial products may be + * obtained by contacting the authors or the Office of Technology Development + * at the University of North Carolina at Chapel Hill . + * + * This software program and documentation are copyrighted by the University of + * North Carolina at Chapel Hill. The software program and documentation are + * supplied "as is," without any accompanying services from the University of + * North Carolina at Chapel Hill or the authors. The University of North + * Carolina at Chapel Hill and the authors do not warrant that the operation of + * the program will be uninterrupted or error-free. The end-user understands + * that the program was developed for research purposes and is advised not to + * rely exclusively on the program for any reason. + * + * IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE + * AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + * OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA + * AT CHAPEL HILL OR THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY + * DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY + * STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND + * THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, + * ENHANCEMENTS, OR MODIFICATIONS. + * + * Please send all BUG REPORTS to . + * + * The authors may be contacted via: + * + * Pavel Krajcevski + * Dept of Computer Science + * 201 S Columbia St + * Frederick P. Brooks, Jr. Computer Science Bldg + * Chapel Hill, NC 27599-3175 + * USA + * + * + */ + +#ifndef BASE_INCLUDE_MATRIX4X4_H_ +#define BASE_INCLUDE_MATRIX4X4_H_ + +#include "MatrixSquare.h" + +namespace FasTC { + + template + class Matrix4x4 : public MatrixSquare { + + public: + + // Constructors + Matrix4x4() { } + Matrix4x4(const MatrixSquare &other) + : MatrixSquare(other) { } + + Matrix4x4(const MatrixBase &other) + : MatrixSquare(other) { } + }; +}; + +#endif // BASE_INCLUDE_MATRIX3X3_H_ From d4ec0a3b3b59e6d94f0cf76eb34dd1abee887fe9 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 15:48:08 -0500 Subject: [PATCH 24/30] Stub out remaining tests --- Base/test/TestMatrix.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp index 7345931..0c3423f 100644 --- a/Base/test/TestMatrix.cpp +++ b/Base/test/TestMatrix.cpp @@ -132,3 +132,38 @@ TEST(MatrixBase, CastVector) { } } +TEST(MatrixBase, MatrixMultiplication) { + // Stub + EXPECT_EQ(0, 1); +} + +TEST(MatrixBase, VectorMultiplication) { + // Stub + EXPECT_EQ(0, 1); +} + +TEST(MatrixSquare, Constructors) { + // Stub + EXPECT_EQ(0, 1); +} + +TEST(MatrixSquare, EigenvalueCalculation) { + // Stub + EXPECT_EQ(0, 1); +} + +TEST(Matrix2x2, Constructors) { + // Stub + EXPECT_EQ(0, 1); +} + +TEST(Matrix3x3, Constructors) { + // Stub + EXPECT_EQ(0, 1); +} + +TEST(Matrix4x4, Constructors) { + // Stub + EXPECT_EQ(0, 1); +} + From 98bc157e00dbc81f1bf5dd217c0778c5b44b8eb2 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 16:11:25 -0500 Subject: [PATCH 25/30] Add matrix multiplication test --- Base/test/TestMatrix.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp index 0c3423f..baf3898 100644 --- a/Base/test/TestMatrix.cpp +++ b/Base/test/TestMatrix.cpp @@ -133,8 +133,27 @@ TEST(MatrixBase, CastVector) { } TEST(MatrixBase, MatrixMultiplication) { - // Stub - EXPECT_EQ(0, 1); + FasTC::MatrixBase a; + a(0, 0) = 1; a(0, 1) = 2; a(0, 2) = 3; + a(1, 0) = 4; a(1, 1) = 5; a(1, 2) = 6; + + FasTC::MatrixBase b; + b(0, 0) = -1; b(0, 1) = 2; b(0, 2) = -4; b(0, 3) = 5; b(0, 4) = 0; + b(1, 0) = 1; b(1, 1) = 2; b(1, 2) = 4; b(1, 3) = 6; b(1, 4) = 3; + b(2, 0) = -1; b(2, 1) = -2; b(2, 2) = -3; b(2, 3) = -4; b(2, 4) = 5; + + FasTC::MatrixBase amb = a * b; + EXPECT_NEAR(amb(0, 0), -2, kEpsilon); + EXPECT_NEAR(amb(0, 1), 0, kEpsilon); + EXPECT_NEAR(amb(0, 2), -5, kEpsilon); + EXPECT_NEAR(amb(0, 3), 5, kEpsilon); + EXPECT_NEAR(amb(0, 4), 21, kEpsilon); + + EXPECT_NEAR(amb(1, 0), -5, kEpsilon); + EXPECT_NEAR(amb(1, 1), 6, kEpsilon); + EXPECT_NEAR(amb(1, 2), -14, kEpsilon); + EXPECT_NEAR(amb(1, 3), 26, kEpsilon); + EXPECT_NEAR(amb(1, 4), 45, kEpsilon); } TEST(MatrixBase, VectorMultiplication) { From 0c4b226c7891b87da4d08b8d8c3fbbb3d8629bf1 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 20 Feb 2014 16:15:13 -0500 Subject: [PATCH 26/30] Add matrix transpose --- Base/include/MatrixBase.h | 11 +++++++++++ Base/test/TestMatrix.cpp | 15 +++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/Base/include/MatrixBase.h b/Base/include/MatrixBase.h index 195250f..9562766 100644 --- a/Base/include/MatrixBase.h +++ b/Base/include/MatrixBase.h @@ -98,6 +98,17 @@ namespace FasTC { return result; } + // Transposition + MatrixBase Transpose() const { + MatrixBase result; + for(int r = 0; r < nRows; r++) { + for(int c = 0; c < nCols; c++) { + result(c, r) = (*this)(r, c); + } + } + return result; + } + // Double dot product template T DDot(const MatrixBase<_T, nRows, nCols> &m) { diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp index baf3898..08ba2bb 100644 --- a/Base/test/TestMatrix.cpp +++ b/Base/test/TestMatrix.cpp @@ -156,6 +156,21 @@ TEST(MatrixBase, MatrixMultiplication) { EXPECT_NEAR(amb(1, 4), 45, kEpsilon); } +TEST(MatrixBase, Transposition) { + FasTC::MatrixBase a; + a(0, 0) = -1; a(0, 1) = 2; a(0, 2) = -4; a(0, 3) = 5; a(0, 4) = 0; + a(1, 0) = 1; a(1, 1) = 2; a(1, 2) = 4; a(1, 3) = 6; a(1, 4) = 3; + a(2, 0) = -1; a(2, 1) = -2; a(2, 2) = -3; a(2, 3) = -4; a(2, 4) = 5; + + FasTC::MatrixBase b = a.Transpose(); + + for(int i = 0; i < 3; i++) { + for(int j = 0; j < 5; j++) { + EXPECT_EQ(a(i, j), b(j, i)); + } + } +} + TEST(MatrixBase, VectorMultiplication) { // Stub EXPECT_EQ(0, 1); From 05eeb09f365cd80b2cff70ac9542f5f9c308fca5 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Fri, 21 Feb 2014 16:11:49 -0500 Subject: [PATCH 27/30] Constify --- Base/include/MatrixBase.h | 2 +- Base/include/VectorBase.h | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Base/include/MatrixBase.h b/Base/include/MatrixBase.h index 9562766..ba431c1 100644 --- a/Base/include/MatrixBase.h +++ b/Base/include/MatrixBase.h @@ -73,7 +73,7 @@ namespace FasTC { // Matrix multiplication template - MatrixBase operator*(const MatrixBase<_T, nCols, nTarget> &m) { + MatrixBase MultiplyMatrix(const MatrixBase<_T, nCols, nTarget> &m) const { MatrixBase result; for(int r = 0; r < nRows; r++) for(int c = 0; c < nTarget; c++) { diff --git a/Base/include/VectorBase.h b/Base/include/VectorBase.h index c3df4b4..e313b90 100644 --- a/Base/include/VectorBase.h +++ b/Base/include/VectorBase.h @@ -198,7 +198,7 @@ namespace FasTC { MultSwitch(const TypeOne &a, const TypeTwo &b) : m_A(a), m_B(b) { } - ResultType GetMultiplication() { return m_A * m_B; } + ResultType GetMultiplication() const { return m_A * m_B; } }; template @@ -216,7 +216,7 @@ namespace FasTC { MultSwitch(const TypeOne &a, const TypeTwo &b) : m_A(a), m_B(b) { } - ResultType GetMultiplication() { return ScalarMultiply(m_B, m_A); } + ResultType GetMultiplication() const { return ScalarMultiply(m_B, m_A); } }; template @@ -234,7 +234,7 @@ namespace FasTC { MultSwitch(const TypeOne &a, const TypeTwo &b) : m_A(a), m_B(b) { } - ResultType GetMultiplication() { return ScalarMultiply(m_A, m_B); } + ResultType GetMultiplication() const { return ScalarMultiply(m_A, m_B); } }; template @@ -252,7 +252,7 @@ namespace FasTC { MultSwitch(const TypeOne &a, const TypeTwo &b) : m_A(a), m_B(b) { } - ResultType GetMultiplication() { return m_A.Dot(m_B); } + ResultType GetMultiplication() const { return m_A.Dot(m_B); } }; template From 8b9e8cd9b51ee0a54c145fbb9036c17b692a87b0 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Fri, 21 Feb 2014 16:18:00 -0500 Subject: [PATCH 28/30] Add matrix multiplication infrastructure --- Base/include/MatrixBase.h | 116 ++++++++++++++++++++++++++++++++++---- Base/test/TestMatrix.cpp | 32 +++++++++-- 2 files changed, 131 insertions(+), 17 deletions(-) diff --git a/Base/include/MatrixBase.h b/Base/include/MatrixBase.h index ba431c1..5bd4c1e 100644 --- a/Base/include/MatrixBase.h +++ b/Base/include/MatrixBase.h @@ -30,11 +30,17 @@ namespace FasTC { template - class MatrixBase : public VectorBase { - private: - typedef VectorBase Base; + class MatrixBase { + protected: + + // Vector representation + T mat[nRows * nCols]; + public: - static const int Size = Base::Size; + typedef T ScalarType; + static const int kNumRows = nRows; + static const int kNumCols = nCols; + static const int Size = kNumCols * kNumRows; // Constructors MatrixBase() { } @@ -45,16 +51,16 @@ namespace FasTC { } // Accessors - T &operator()(int idx) { return Base::operator()(idx); } - T &operator[](int idx) { return Base::operator[](idx); } - const T &operator()(int idx) const { return Base::operator()(idx); } - const T &operator[](int idx) const { return Base::operator[](idx); } + T &operator()(int idx) { return mat[idx]; } + T &operator[](int idx) { return mat[idx]; } + const T &operator()(int idx) const { return mat[idx]; } + const T &operator[](int idx) const { return mat[idx]; } T &operator()(int r, int c) { return (*this)[r * nCols + c]; } const T &operator() (int r, int c) const { return (*this)[r * nCols + c]; } // Allow casts to the respective array representation... - operator const T *() const { return this->vec; } + operator const T *() const { return this->mat; } MatrixBase &operator=(const T *v) { for(int i = 0; i < Size; i++) (*this)[i] = v[i]; @@ -66,7 +72,7 @@ namespace FasTC { operator MatrixBase<_T, nRows, nCols>() const { MatrixBase<_T, nRows, nCols> ret; for(int i = 0; i < Size; i++) { - ret[i] = static_cast<_T>(this->vec[i]); + ret[i] = static_cast<_T>(mat[i]); } return ret; } @@ -87,8 +93,20 @@ namespace FasTC { // Vector multiplication -- treat vectors as Nx1 matrices... template - VectorBase operator*(const VectorBase<_T, nCols> &v) { + VectorBase MultiplyVectorLeft(const VectorBase<_T, nRows> &v) const { VectorBase result; + for(int j = 0; j < nCols; j++) { + result(j) = 0; + for(int r = 0; r < nRows; r++) { + result(j) += (*this)(r, j) * v(r); + } + } + return result; + } + + template + VectorBase MultiplyVectorRight(const VectorBase<_T, nCols> &v) const { + VectorBase result; for(int r = 0; r < nRows; r++) { result(r) = 0; for(int j = 0; j < nCols; j++) { @@ -111,14 +129,88 @@ namespace FasTC { // Double dot product template - T DDot(const MatrixBase<_T, nRows, nCols> &m) { + T DDot(const MatrixBase<_T, nRows, nCols> &m) const { T result = 0; for(int i = 0; i < Size; i++) { result += (*this)[i] * m[i]; } return result; } + }; + template + class VectorTraits > { + public: + static const EVectorType kVectorType = eVectorType_Matrix; + }; + + #define REGISTER_MATRIX_TYPE(TYPE) \ + template<> \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Matrix; \ + } + + #define REGISTER_ONE_TEMPLATE_MATRIX_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Matrix; \ + } + + // Define matrix multiplication for * operator + template + class MultSwitch< + eVectorType_Matrix, + eVectorType_Vector, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef VectorBase ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_A.MultiplyVectorRight(m_B); } + }; + + template + class MultSwitch< + eVectorType_Vector, + eVectorType_Matrix, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef VectorBase ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_B.MultiplyVectorLeft(m_A); } + }; + + template + class MultSwitch< + eVectorType_Matrix, + eVectorType_Matrix, + TypeOne, TypeTwo> { + private: + const TypeOne &m_A; + const TypeTwo &m_B; + + public: + typedef MatrixBase ResultType; + + MultSwitch(const TypeOne &a, const TypeTwo &b) + : m_A(a), m_B(b) { } + + ResultType GetMultiplication() const { return m_A.MultiplyMatrix(m_B); } }; // Outer product... diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp index 08ba2bb..2e26cf5 100644 --- a/Base/test/TestMatrix.cpp +++ b/Base/test/TestMatrix.cpp @@ -158,9 +158,9 @@ TEST(MatrixBase, MatrixMultiplication) { TEST(MatrixBase, Transposition) { FasTC::MatrixBase a; - a(0, 0) = -1; a(0, 1) = 2; a(0, 2) = -4; a(0, 3) = 5; a(0, 4) = 0; - a(1, 0) = 1; a(1, 1) = 2; a(1, 2) = 4; a(1, 3) = 6; a(1, 4) = 3; - a(2, 0) = -1; a(2, 1) = -2; a(2, 2) = -3; a(2, 3) = -4; a(2, 4) = 5; + a(0, 0) = -1; a(0, 1) = 2; a(0, 2) = -4; a(0, 3) = 5; a(0, 4) = 0; + a(1, 0) = 1; a(1, 1) = 2; a(1, 2) = 4; a(1, 3) = 6; a(1, 4) = 3; + a(2, 0) = -1; a(2, 1) = -2; a(2, 2) = -3; a(2, 3) = -4; a(2, 4) = 5; FasTC::MatrixBase b = a.Transpose(); @@ -172,8 +172,30 @@ TEST(MatrixBase, Transposition) { } TEST(MatrixBase, VectorMultiplication) { - // Stub - EXPECT_EQ(0, 1); + + FasTC::MatrixBase a; + a(0, 0) = -1; a(0, 1) = 2; a(0, 2) = -4; a(0, 3) = 5; a(0, 4) = 0; + a(1, 0) = 1; a(1, 1) = 2; a(1, 2) = 4; a(1, 3) = 6; a(1, 4) = 3; + a(2, 0) = -1; a(2, 1) = -2; a(2, 2) = -3; a(2, 3) = -4; a(2, 4) = 5; + + FasTC::VectorBase v; + for(int i = 0; i < 5; i++) v[i] = i + 1; + + FasTC::VectorBase u = a * v; + EXPECT_EQ(u[0], -1 + (2 * 2) - (4 * 3) + (5 * 4)); + EXPECT_EQ(u[1], 1 + (2 * 2) + (4 * 3) + (6 * 4) + (3 * 5)); + EXPECT_EQ(u[2], -1 + (-2 * 2) - (3 * 3) - (4 * 4) + (5 * 5)); + + ///// + + for(int i = 0; i < 3; i++) u[i] = i + 1; + v = u * a; + + EXPECT_EQ(v[0], -1 + (1 * 2) - (1 * 3)); + EXPECT_EQ(v[1], 2 + (2 * 2) - (2 * 3)); + EXPECT_EQ(v[2], -4 + (4 * 2) - (3 * 3)); + EXPECT_EQ(v[3], 5 + (6 * 2) - (4 * 3)); + EXPECT_EQ(v[4], 0 + (3 * 2) + (5 * 3)); } TEST(MatrixSquare, Constructors) { From ba0b5df59e9c719a6e67ee028355a980ee3256d4 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Fri, 21 Feb 2014 17:45:07 -0500 Subject: [PATCH 29/30] Finish matrix unit tests --- Base/include/Matrix2x2.h | 47 +++++++++++++ Base/include/Matrix3x3.h | 14 ++-- Base/include/Matrix4x4.h | 6 +- Base/include/MatrixBase.h | 7 ++ Base/include/MatrixSquare.h | 74 +++++++++++++------ Base/test/TestMatrix.cpp | 137 +++++++++++++++++++++++++++++++++--- 6 files changed, 242 insertions(+), 43 deletions(-) create mode 100644 Base/include/Matrix2x2.h diff --git a/Base/include/Matrix2x2.h b/Base/include/Matrix2x2.h new file mode 100644 index 0000000..25afd20 --- /dev/null +++ b/Base/include/Matrix2x2.h @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Pavel Krajcevski + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + ******************************************************************************/ + +#ifndef BASE_INCLUDE_MATRIX2X2_H_ +#define BASE_INCLUDE_MATRIX2X2_H_ + +#include "MatrixSquare.h" + +namespace FasTC { + + template + class Matrix2x2 : public MatrixSquare { + public: + // Constructors + Matrix2x2() { } + Matrix2x2(const Matrix2x2 &other) + : MatrixSquare(other) { } + Matrix2x2(const MatrixSquare &other) + : MatrixSquare(other) { } + Matrix2x2(const MatrixBase &other) + : MatrixSquare(other) { } + }; + REGISTER_ONE_TEMPLATE_MATRIX_TYPE(Matrix2x2); +}; + +#endif // BASE_INCLUDE_MATRIX2X2_H_ diff --git a/Base/include/Matrix3x3.h b/Base/include/Matrix3x3.h index b5d226b..60edf73 100644 --- a/Base/include/Matrix3x3.h +++ b/Base/include/Matrix3x3.h @@ -31,17 +31,17 @@ namespace FasTC { template class Matrix3x3 : public MatrixSquare { - public: - // Constructors Matrix3x3() { } - Matrix3x3(const MatrixSquare &other) { - for(int i = 0; i < kNumElements; i++) { - mat[i] = other[i]; - } - } + Matrix3x3(const Matrix3x3 &other) + : MatrixSquare(other) { } + Matrix3x3(const MatrixSquare &other) + : MatrixSquare(other) { } + Matrix3x3(const MatrixBase &other) + : MatrixSquare(other) { } }; + REGISTER_ONE_TEMPLATE_MATRIX_TYPE(Matrix3x3); }; #endif // BASE_INCLUDE_MATRIX3X3_H_ diff --git a/Base/include/Matrix4x4.h b/Base/include/Matrix4x4.h index 4a21bf9..5fe18ee 100644 --- a/Base/include/Matrix4x4.h +++ b/Base/include/Matrix4x4.h @@ -59,17 +59,17 @@ namespace FasTC { template class Matrix4x4 : public MatrixSquare { - public: - // Constructors Matrix4x4() { } + Matrix4x4(const Matrix4x4 &other) + : MatrixSquare(other) { } Matrix4x4(const MatrixSquare &other) : MatrixSquare(other) { } - Matrix4x4(const MatrixBase &other) : MatrixSquare(other) { } }; + REGISTER_ONE_TEMPLATE_MATRIX_TYPE(Matrix4x4); }; #endif // BASE_INCLUDE_MATRIX3X3_H_ diff --git a/Base/include/MatrixBase.h b/Base/include/MatrixBase.h index 5bd4c1e..94d8aa2 100644 --- a/Base/include/MatrixBase.h +++ b/Base/include/MatrixBase.h @@ -158,6 +158,13 @@ namespace FasTC { static const EVectorType kVectorType = eVectorType_Matrix; \ } + #define REGISTER_ONE_TEMPLATE_MATRIX_SIZED_TYPE(TYPE) \ + template \ + class VectorTraits< TYPE > { \ + public: \ + static const EVectorType kVectorType = eVectorType_Matrix; \ + } + // Define matrix multiplication for * operator template class MultSwitch< diff --git a/Base/include/MatrixSquare.h b/Base/include/MatrixSquare.h index 8c20752..df887b0 100644 --- a/Base/include/MatrixSquare.h +++ b/Base/include/MatrixSquare.h @@ -26,6 +26,8 @@ #define BASE_INCLUDE_MATRIXSQUARE_H_ #include "MatrixBase.h" +#include +#include namespace FasTC { @@ -40,54 +42,82 @@ namespace FasTC { MatrixSquare(const MatrixBase &other) : MatrixBase(other) { } + MatrixSquare Transpose() const { + return MatrixBase::Transpose(); + } + // Does power iteration to determine the principal eigenvector and eigenvalue. // Returns them in eigVec and eigVal after kMaxNumIterations - int PowerMethod(VectorBase &eigVec, T *eigVal = NULL, - const int kMaxNumIterations = 200) { + int PowerMethod(VectorBase &eigVec, + T *eigVal = NULL, + const int kMaxNumIterations = 200, + const unsigned int kSeed = time(NULL)) { + + srand(kSeed); int numIterations = 0; - // !SPEED! Find eigenvectors by using the power method. This is good because the - // matrix is only 4x4, which allows us to use SIMD... VectorBase b; for(int i = 0; i < N; i++) - b[i] = T(1.0); - - b /= b.Length(); + b[i] = static_cast(rand()); + b.Normalize(); + bool badEigenValue = false; bool fixed = false; numIterations = 0; while(!fixed && ++numIterations < kMaxNumIterations) { - VectorBase newB = (*this).operator*(b); + VectorBase newB = (*this) * b; - // !HACK! If the principal eigenvector of the covariance matrix - // converges to zero, that means that the points lie equally - // spaced on a sphere in this space. In this (extremely rare) - // situation, just choose a point and use it as the principal - // direction. + // !HACK! If the principal eigenvector of the matrix + // converges to zero, that could mean that there is no + // principal eigenvector. However, that may be due to + // poor initialization of the random vector, so rerandomize + // and try again. const float newBlen = newB.Length(); if(newBlen < 1e-10) { - eigVec = b; - if(eigVal) *eigVal = 0.0; - return numIterations; + if(badEigenValue) { + eigVec = b; + if(eigVal) *eigVal = 0.0; + return numIterations; + } + + VectorBase b; + for(int i = 0; i < N; i++) + b[i] = static_cast(rand()); + + b.Normalize(); + badEigenValue = true; } - T len = newB.Length(); - newB /= len; - if(eigVal) - *eigVal = len; + // Normalize + newB.Normalize(); - if(fabs(1.0f - (b.Dot(newB))) < 1e-5) + // If the new eigenvector is close enough to the old one, + // then we've converged. + if(fabs(1.0f - (b.Dot(newB))) < 1e-8) fixed = true; + // Save and continue. b = newB; } - eigVec = b; + // Store the eigenvector in the proper variable. + eigVec = b; + + // Store eigenvalue if it was requested + if(eigVal) { + VectorBase result = (*this) * b; + *eigVal = result.Length() / b.Length(); + } + return numIterations; } + private: + }; + REGISTER_ONE_TEMPLATE_MATRIX_SIZED_TYPE(MatrixSquare); + }; #endif // BASE_INCLUDE_MATRIXSQUARE_H_ diff --git a/Base/test/TestMatrix.cpp b/Base/test/TestMatrix.cpp index 2e26cf5..55a4aa9 100644 --- a/Base/test/TestMatrix.cpp +++ b/Base/test/TestMatrix.cpp @@ -123,7 +123,13 @@ TEST(MatrixBase, PointerConversion) { } TEST(MatrixBase, CastVector) { + srand(time(NULL)); + FasTC::MatrixBase v3f; + for(int i = 0; i < 6; i++) { + v3f[i] = static_cast(rand()); + } + FasTC::MatrixBase v3d = v3f; FasTC::MatrixBase v3i = v3f; for(int i = 0; i < 3*2; i++) { @@ -198,28 +204,137 @@ TEST(MatrixBase, VectorMultiplication) { EXPECT_EQ(v[4], 0 + (3 * 2) + (5 * 3)); } +//////////////////////////////////////////////////////////////////////////////// + +#include "MatrixSquare.h" + TEST(MatrixSquare, Constructors) { - // Stub - EXPECT_EQ(0, 1); + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; m(0, 2) = 3; + m(1, 0) = 2; m(1, 1) = 3; m(1, 2) = 4; + m(2, 0) = 3; m(2, 1) = 4; m(2, 2) = 5; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::MatrixSquare fsqm(m); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::MatrixSquare fcsqm(sqm); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } } -TEST(MatrixSquare, EigenvalueCalculation) { - // Stub - EXPECT_EQ(0, 1); +TEST(MatrixSquare, PowerMethod) { + FasTC::MatrixSquare A; + A(0, 0) = 0.8f; A(0, 1) = 0.3f; + A(1, 0) = 0.2f; A(1, 1) = 0.7f; + + double e; + FasTC::VectorBase x; + A.PowerMethod(x, &e, 20, 200); + + EXPECT_NEAR(x[0], 0.83205f, 0.0001); + EXPECT_NEAR(x[1], 0.5547f, 0.0001); + + EXPECT_NEAR(e, 1.f, 0.0001); } +//////////////////////////////////////////////////////////////////////////////// + +#include "Matrix2x2.h" + TEST(Matrix2x2, Constructors) { - // Stub - EXPECT_EQ(0, 1); + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; + m(1, 0) = 2; m(1, 1) = 3; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 4; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::Matrix2x2 tbtm (m); + for(int i = 0; i < 4; i++) { + EXPECT_EQ(m[i], tbtm[i]); + } + + FasTC::Matrix2x2 fsqm(m); + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::Matrix2x2 fcsqm(sqm); + for(int i = 0; i < 4; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } } +//////////////////////////////////////////////////////////////////////////////// + +#include "Matrix3x3.h" + TEST(Matrix3x3, Constructors) { - // Stub - EXPECT_EQ(0, 1); + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; m(0, 2) = 3; + m(1, 0) = 2; m(1, 1) = 3; m(1, 2) = 4; + m(2, 0) = 3; m(2, 1) = 4; m(2, 2) = 5; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::Matrix3x3 tbtm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], tbtm[i]); + } + + FasTC::Matrix3x3 fsqm(m); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::Matrix3x3 fcsqm(sqm); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } } +//////////////////////////////////////////////////////////////////////////////// + +#include "Matrix4x4.h" + TEST(Matrix4x4, Constructors) { - // Stub - EXPECT_EQ(0, 1); + FasTC::MatrixBase m; + m(0, 0) = 1; m(0, 1) = 2; m(0, 2) = 3; m(0, 3) = 4; + m(1, 0) = 2; m(1, 1) = 3; m(1, 2) = 4; m(1, 3) = 5; + m(2, 0) = 3; m(2, 1) = 4; m(2, 2) = 5; m(2, 3) = 6; + m(3, 0) = 4; m(3, 1) = 5; m(3, 2) = 6; m(3, 3) = 7; + + FasTC::MatrixSquare sqm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], sqm[i]); + } + + FasTC::Matrix4x4 tbtm (m); + for(int i = 0; i < 9; i++) { + EXPECT_EQ(m[i], tbtm[i]); + } + + FasTC::Matrix4x4 fsqm(m); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(m[i], fsqm[i], kEpsilon); + } + + FasTC::Matrix4x4 fcsqm(sqm); + for(int i = 0; i < 9; i++) { + EXPECT_NEAR(fcsqm[i], sqm[i], kEpsilon); + } } From a7a389b41c72a1657c331b11aa503125c362be27 Mon Sep 17 00:00:00 2001 From: Pavel Krajcevski Date: Thu, 27 Feb 2014 11:55:00 -0500 Subject: [PATCH 30/30] Remove this folder since I don't think that this tool is gonna happen --- QtGUI/CMakeLists.txt | 41 ----------------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 QtGUI/CMakeLists.txt diff --git a/QtGUI/CMakeLists.txt b/QtGUI/CMakeLists.txt deleted file mode 100644 index 9d13dc4..0000000 --- a/QtGUI/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -# FasTC -# Copyright (c) 2012 University of North Carolina at Chapel Hill. All rights reserved. -# -# Permission to use, copy, modify, and distribute this software and its documentation for educational, -# research, and non-profit purposes, without fee, and without a written agreement is hereby granted, -# provided that the above copyright notice, this paragraph, and the following four paragraphs appear -# in all copies. -# -# Permission to incorporate this software into commercial products may be obtained by contacting the -# authors or the Office of Technology Development at the University of North Carolina at Chapel Hill . -# -# This software program and documentation are copyrighted by the University of North Carolina at Chapel Hill. -# The software program and documentation are supplied "as is," without any accompanying services from the -# University of North Carolina at Chapel Hill or the authors. The University of North Carolina at Chapel Hill -# and the authors do not warrant that the operation of the program will be uninterrupted or error-free. The -# end-user understands that the program was developed for research purposes and is advised not to rely -# exclusively on the program for any reason. -# -# IN NO EVENT SHALL THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE AUTHORS BE LIABLE TO ANY PARTY FOR -# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE -# USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL OR THE -# AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# THE UNIVERSITY OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, -# BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE AND ANY -# STATUTORY WARRANTY OF NON-INFRINGEMENT. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY -# OF NORTH CAROLINA AT CHAPEL HILL AND THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, -# ENHANCEMENTS, OR MODIFICATIONS. -# -# Please send all BUG REPORTS to . -# -# The authors may be contacted via: -# -# Pavel Krajcevski -# Dept of Computer Science -# 201 S Columbia St -# Frederick P. Brooks, Jr. Computer Science Bldg -# Chapel Hill, NC 27599-3175 -# USA -# -#